nesticot commited on
Commit
b704539
·
1 Parent(s): 0044de7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +775 -274
app.py CHANGED
@@ -6,7 +6,6 @@ import seaborn as sns
6
  import matplotlib.pyplot as plt
7
  from matplotlib.pyplot import figure
8
  from matplotlib.offsetbox import OffsetImage, AnnotationBbox
9
- from scipy import stats
10
  import matplotlib.lines as mlines
11
  import matplotlib.transforms as mtransforms
12
  import numpy as np
@@ -31,13 +30,7 @@ plt.style.use('fivethirtyeight')
31
  sns.set_context("notebook")
32
  import warnings
33
  warnings.filterwarnings('ignore')
34
- # import yfpy
35
- # from yfpy.query import YahooFantasySportsQuery
36
- # import yahoo_oauth
37
- import json
38
- #import openpyxl
39
- # from sklearn import preprocessing
40
- from datetime import timedelta
41
  # import dataframe_image as dfi
42
  # from google.colab import drive
43
  def percentile(n):
@@ -62,31 +55,49 @@ import math
62
  # import matplotlib.colors as mcolors
63
  # from matplotlib.ticker import FuncFormatter
64
  # from matplotlib.font_manager import FontProperties
65
-
66
  import numpy as np
67
  # import matplotlib.pyplot as plt
68
  import matplotlib.colors
69
 
70
- # import undetected_chromedriver as uc
71
- # from selenium import webdriver
72
- # from seleniumbase import Driver
73
-
74
- # driver = Driver(uc=True)
75
- # driver.get('https://www.naturalstattrick.com')
76
-
77
- #x,y,c = zip(*np.random.rand(30,3)*4-2)
78
-
79
- #norm=plt.Normalize(-2,2)
80
- co = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#ffffff","#F0E442"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
 
83
- try:
84
- data_r = requests.get("https://pub-api-ro.fantasysports.yahoo.com/fantasy/v2/league/427.l.public;out=settings/players;position=ALL;start=0;count=3000;sort=average_pick;search=;out=percent_owned;out=auction_values,ranks;ranks=season;ranks_by_position=season;out=expert_ranks;expert_ranks.rank_type=projected_season_remaining/draft_analysis;cut_types=diamond;slices=last7days?format=json_f").json()
85
- key_check = data_r['fantasy_content']['league']['players']
86
 
87
- except KeyError:
88
- data_r = requests.get("https://pub-api-ro.fantasysports.yahoo.com/fantasy/v2/league/427.l.public;out=settings/players;position=ALL;start=0;count=1151;sort=average_pick;search=;out=percent_owned;out=auction_values,ranks;ranks=season;ranks_by_position=season;out=expert_ranks;expert_ranks.rank_type=projected_season_remaining/draft_analysis;cut_types=diamond;slices=last7days?format=json_f").json()
89
- print('key_checked')
90
 
91
  total_list = []
92
 
@@ -108,95 +119,33 @@ for x in data_r['fantasy_content']['league']['players']:
108
  single_list.append(0)
109
  total_list.append(single_list)
110
 
 
111
 
112
- yahoo_df = pd.DataFrame(total_list,columns = ['player_id','rank_value','full','first','last','average_pick','average_auction_cost','display_position','editorial_team_abbr','percent_owned'])
113
- yahoo_df_2 = yahoo_df.copy()
114
-
115
- # # Write your code here.
116
- # response = requests.get("https://www.naturalstattrick.com/playerlist.php?fromseason=20232024&thruseason=20232024&stype=2&sit=all&stdoi=oi&rate=n")
117
- # soup = BeautifulSoup(response.text, 'html.parser')
118
- # table_rows = soup.findAll('tr')
119
- # table_rows = table_rows[1:-1]
120
- # table_rows[0].findAll('td')
121
-
122
- # player_name = []
123
- # player_position = []
124
- # player_team = []
125
- # player_id = []
126
-
127
- # for i in range(0,len(table_rows)-1):
128
- # player_name.append(str(table_rows[i].findAll('td')[0].contents[0]))
129
- # player_position.append(table_rows[i].findAll('td')[1].contents[0])
130
- # player_team.append(table_rows[i].findAll('td')[2].contents[0])
131
- # player_id.append(str(table_rows[i].findAll('td')[3].contents[0])[-76:][:7])
132
-
133
- # player_id_df = pd.DataFrame({'Player':player_name,'Player ID':player_id,'Position':player_position,'Team':player_team})
134
- # #player_id_df.index.name = 'Player Name'
135
- # player_id_df.head()
136
-
137
- # skater_df = player_id_df[player_id_df['Position'] != 'G']
138
- # goalie_df = player_id_df[player_id_df['Position'] == 'G']
139
 
140
- season = 20232024
141
- seasontype = 2
 
 
 
 
142
 
143
- def nat_stat_trick_range_pp_gp(rookie='n',start_date='2022-10-01',end_date=str(pd.to_datetime(datetime.now(pytz.timezone('US/Pacific')).strftime('%Y-%m-%d')).date()),sit='all',gp=1):
144
- time.sleep(2)
145
- url = f'https://www.naturalstattrick.com/playerteams.php?fromseason={season}&thruseason={season}&stype={seasontype}&sit=pp&score=all&stdoi=std&rate=y&team=ALL&pos=S&loc=B&toi=0&gpfilt=gpteam&fd=&td=&tgp='+str(gp)+'&lines=single&draftteam=ALL'
146
 
147
- player_list_all = []
148
- response = requests.get(url)
149
- soup = BeautifulSoup(response.text, 'html.parser')
150
- table_rows = soup.findAll('tr')
151
- table_rows = table_rows[1:]
152
 
153
- for j in range(0,len(table_rows)):
154
- p_string = [str(x).strip('<td>').strip('</') for x in list(table_rows[j].findAll('td')) if "<td>" in str(x)]
155
- player_list_all.append([p_string[0]]+[str(table_rows[j].findAll('td')[1]).split('>')[2].split('<')[0]]+p_string[1:]+[str(table_rows[j].findAll('td')[1])[98:105].strip('</a></td>')])
156
- #table_rows[0].findAll('td')
157
 
158
- if soup != "":
159
- columns_list = [str(x).split('>')[1].split('<')[0] for x in soup.findAll('th')]+['player_id']
160
- df_url = pd.DataFrame(data=player_list_all,columns=columns_list)
161
 
162
- df_url = df_url.fillna(0)
163
- df_url['Shots+Hits+Blocks/60'] = df_url['Shots/60'].astype(float)+df_url['Hits/60'].astype(float)+df_url['Shots Blocked/60'].astype(float)
164
- df_url['Shots+Hits/60'] = df_url['Shots/60'].astype(float)+df_url['Hits/60'].astype(float)
165
- #print(url)
166
- return df_url
167
-
168
- team_abv = pd.read_csv('team_abv.csv')
169
- team_dict = team_abv.set_index('team_abv').to_dict()['team_name']
170
-
171
- yahoo_nhl_df = pd.read_csv('yahoo_to_nhl.csv', encoding='unicode_escape')
172
-
173
-
174
- player_games_df = pd.read_csv('player_games_cards.csv',index_col=[0])
175
- team_games_df = pd.read_csv('team_games.csv',index_col=[0])
176
-
177
- team_games_df['game_count'] = team_games_df.groupby('team')['team'].cumcount()+1
178
- team_games_df['max_games'] = team_games_df.groupby('team').game_count.transform('max')
179
- team_games_df['abv'] = team_games_df.team.map(team_abv.set_index('team_name')['team_abv'].to_dict())
180
-
181
- team_games_df = team_games_df.sort_values(by='game_count',ascending=False)
182
-
183
- #team_abv = pd.read_csv('team_abv.csv')
184
-
185
-
186
-
187
- def nat_stat_convert(df):
188
- for i in range(0,len(df.columns)):
189
- if df.columns[i][-3:]=='/60':
190
- if 'ix' not in df.columns[i]:
191
- df[df.columns[i]] = np.round(df[df.columns[i]].astype(float)*df['TOI'].astype(float)/60,0)
192
- df = df.rename(columns={df.columns[i]: df.columns[i].replace('/60','')})
193
- else:
194
- df[df.columns[i]] = df[df.columns[i]].astype(float)*df['TOI'].astype(float)/60
195
- df = df.rename(columns={df.columns[i]: df.columns[i].replace('/60','')})
196
 
197
- df['Faceoffs %'] = df['Faceoffs Won']/(df['Faceoffs Won']+df['Faceoffs Lost'])
198
-
199
- return df
200
 
201
  from shiny import ui, render, App
202
  import matplotlib.image as mpimg
@@ -207,24 +156,12 @@ app_ui = ui.page_fluid(
207
 
208
  ui.panel_sidebar(
209
  #ui.input_date_range("date_range_id", "Date range input",start = statcast_df.game_date.min(), end = statcast_df.game_date.max()),
210
- ui.input_select("team_id", "Select Team",team_dict,width=1,size=1,selected='ANA',),
211
- ui.input_numeric("n_1", "Last Games x", value=1),
212
- ui.input_numeric("n_2", "Last Games y", value=0),
213
- ui.input_numeric("n_3", "Last Games z", value=0),
214
- ui.input_numeric("top_n", "Show top 'n'", value=10),
215
- ui.input_switch("x", "Drop N/A"),
216
  #ui.input_select("ignore_id", "Remove Columns",['Position','Roster%'],multiple=True,selectize=True),
217
- ),
218
-
219
- ui.panel_main(ui.tags.h3(""),
220
- ui.div({"style": "font-size:2.7em;"},ui.output_text("txt_title")),
221
- #ui.tags.h2("Fantasy Hockey Schedule Summary"),
222
- ui.tags.h5("Created By: @TJStats, Data: Natural Stat Trick, Yahoo Fantasy"),
223
- ui.div({"style": "font-size:1.6em;"},ui.output_text("txt")),
224
- ui.output_table("pp_roundup"),
225
- #ui.tags.h5('Legend'),
226
- #ui.tags.h6('An Off Night is defined as a day in which less than half the teams in the NHL are playing'),
227
- #ui.tags.h6('The scores are determined by using games played, off-nights, B2B, and strength of opponents') )
228
  )
229
  ),
230
  )
@@ -243,199 +180,763 @@ from shiny.ui import h2, tags
243
  #print(app_ui)
244
  def server(input, output, session):
245
 
246
-
247
- @output
248
- @render.text
249
- def txt():
250
- return f'{team_dict[input.team_id()]} Last Games PP Summary'
251
-
252
  @output
253
- @render.text
254
- def txt_title():
255
-
256
- return f'Team Last Games PP% Leaders'
 
 
 
 
257
 
 
258
 
 
259
 
260
 
261
 
262
- @output
263
- @render.table
264
- def pp_roundup():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
 
266
- top_n = input.top_n()
267
- n_1 = input.n_1()
268
- n_2 = input.n_2()
269
- n_3 = input.n_3()
270
 
271
- list_of_columns = ['Player', 'Team', 'display_position','percent_owned','L'+str(n_1)+' PP TOI','L'+str(n_2)+' PP TOI','L'+str(n_3)+' PP TOI',
272
- 'L'+str(n_1)+' PP%','L'+str(n_2)+' PP%','L'+str(n_3)+' PP%']
273
 
274
- list_of_columns_name = ['Player', 'Team', 'Position','Roster%','L'+str(n_1)+' PP TOI','L'+str(n_2)+' PP TOI','L'+str(n_3)+' PP TOI',
275
- 'L'+str(n_1)+' PP%','L'+str(n_2)+' PP%','L'+str(n_3)+' PP%']
276
 
277
- if type(n_1) is not int:
278
- n_1 = 1
279
 
280
- if (n_2 == 0) or (n_2 == n_1) or (n_2 == None):
281
- list_of_columns.remove(f'L{str(n_2)} PP TOI')
282
- list_of_columns.remove(f'L{str(n_2)} PP%')
283
- list_of_columns_name.remove(f'L{str(n_2)} PP TOI')
284
- list_of_columns_name.remove(f'L{str(n_2)} PP%')
285
-
286
- if (n_3 == 0) or (n_3 == n_1) or (n_3 == n_2) or (n_3 == None):
287
- list_of_columns.remove(f'L{str(n_3)} PP TOI')
288
- list_of_columns.remove(f'L{str(n_3)} PP%')
289
- list_of_columns_name.remove(f'L{str(n_3)} PP TOI')
290
- list_of_columns_name.remove(f'L{str(n_3)} PP%')
291
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
292
 
293
 
294
- start_date ='2023-09-01'
295
- end_date = '2024-05-01'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
 
297
- df_pp_1 = player_games_df.groupby('Player').head(n_1)
298
- df_pp_2 = player_games_df.groupby('Player').head(n_2)
299
- df_pp_3 = player_games_df.groupby('Player').head(n_3)
300
 
 
 
 
301
 
302
- team_games_df_1 = team_games_df.groupby('team').head(n_1)
303
- team_games_df_2 = team_games_df.groupby('team').head(n_2)
304
- team_games_df_3 = team_games_df.groupby('team').head(n_3)
305
 
306
- df_all_pp_1 = df_pp_1.copy()
307
- df_all_pp_2 = df_pp_2.copy()
308
- df_all_pp_3 = df_pp_3.copy()
309
 
310
- df_all_pp_1_final = df_all_pp_1.groupby(['player_id','Player','Team','Position']).sum()[['TOI_pp']].reset_index()
311
- df_all_pp_2_final = df_all_pp_2.groupby(['player_id','Player','Team','Position']).sum()[['TOI_pp']].reset_index()
312
- df_all_pp_3_final = df_all_pp_3.groupby(['player_id','Player','Team','Position']).sum()[['TOI_pp']].reset_index()
313
 
314
- team_games_df_1_final = team_games_df_1.groupby(['abv']).sum()[['pp_toi']].reset_index()
315
- team_games_df_2_final = team_games_df_2.groupby(['abv']).sum()[['pp_toi']].reset_index()
316
- team_games_df_3_final = team_games_df_3.groupby(['abv']).sum()[['pp_toi']].reset_index()
317
 
318
- df_final = df_all_pp_1_final.merge( df_all_pp_2_final,how='outer',left_on=['player_id'],right_on=['player_id'],suffixes=("","_2"))
319
- df_final = df_final.merge( df_all_pp_3_final,how='outer',left_on=['player_id'],right_on=['player_id'],suffixes=("_1","_3"))
 
 
320
 
321
- team_final = team_games_df_1_final.merge( team_games_df_2_final,how='outer',left_on=['abv'],right_on=['abv'],suffixes=("","_2"))
322
- team_final = team_final.merge( team_games_df_3_final,how='outer',left_on=['abv'],right_on=['abv'],suffixes=("_1","_3"))
 
 
323
 
 
 
 
 
 
 
 
 
 
324
 
325
- df_final = df_final.merge(team_final,left_on='Team_1',right_on='abv')
 
 
 
 
326
 
327
- test = df_final[['player_id','Player_1','Team_1','Position_1','TOI_pp_1','TOI_pp_2','TOI_pp_3','pp_toi_1','pp_toi_2','pp_toi_3']]
328
- test.columns = ['player_id','Player','Team','Position','TOI_1','TOI_2','TOI_3','pp_toi_1','pp_toi_2','pp_toi_3']
329
- test = test.fillna('0')
330
 
331
 
332
- test['PP%_1'] = test['TOI_1'].astype(float)/ test['pp_toi_1'].astype(float)
333
- test['PP%_2'] = test['TOI_2'].astype(float)/ test['pp_toi_2'].astype(float)
334
- test['PP%_3'] = test['TOI_3'].astype(float)/ test['pp_toi_3'].astype(float)
335
- # test = test.fillna(0)
336
- test['TOI_1'] = ["%d:%02d" % (int(x),(x*60)%60) for x in test['TOI_1'].astype(float)]
337
- test['TOI_2'] = ["%d:%02d" % (int(x),(x*60)%60) for x in test['TOI_2'].astype(float)]
338
- test['TOI_3'] = ["%d:%02d" % (int(x),(x*60)%60) for x in test['TOI_3'].astype(float)]
339
- test = test.drop(['pp_toi_1','pp_toi_2','pp_toi_3'],axis=1)
340
- test.columns = ['player_id','Player','Team','Position','L'+str(n_1)+' PP TOI','L'+str(n_2)+' PP TOI','L'+str(n_3)+' PP TOI','L'+str(n_1)+' PP%','L'+str(n_2)+' PP%','L'+str(n_3)+' PP%']
341
 
342
 
343
- yahoo_df = yahoo_df_2.merge(yahoo_nhl_df,left_on = 'player_id',right_on='player_id_yahoo',suffixes=['','_y'])
344
- yahoo_df.nhl_id = yahoo_df.nhl_id.astype(float)
345
- test.player_id = test.player_id.astype(float)
 
 
 
 
 
 
 
 
 
 
346
 
347
- test = test.merge(right=yahoo_df,left_on='player_id',right_on='nhl_id',suffixes=['','_y'],how='left')
 
 
 
 
 
 
 
348
 
349
 
350
- test.loc[test.display_position.isna(),'display_position'] = test.loc[test.display_position.isna(),'Position']
351
- test.display_position = test.display_position.replace({'L':'LW','R':'RW'})
352
- test.percent_owned = test.percent_owned.fillna(0)
 
 
 
 
353
 
354
-
 
 
 
 
 
 
355
 
 
 
 
 
 
 
 
 
 
356
 
357
- print('Column List')
358
- print(test.columns)
 
 
 
 
359
 
360
 
361
- print(list_of_columns)
362
- test = test[list_of_columns]
363
- test = test.rename(columns={'percent_owned':'Roster%'})
364
- test = test.rename(columns={'display_position':'Position'})
365
-
366
 
367
- top_d_score = test[(test.Team==input.team_id())].sort_values(by=['L'+str(n_1)+' PP%'],ascending=False).reset_index(drop=True)
368
-
369
- if input.x():
370
- top_d_score = top_d_score.dropna(axis='columns')
371
-
372
- top_d_score = top_d_score.head(min(len(top_d_score),top_n))
373
 
 
374
 
375
- #top_d_score.columns = list_of_columns_name
376
 
377
-
378
 
379
- top_d_score['Deployment'] = "PP2"
380
- top_d_score['Deployment'][0:5] = "PP1"
381
 
382
-
383
- cols = top_d_score.columns.tolist();
384
- print('we made it here',cols)
385
-
386
- # for i in list(input.ignore_id()):
387
- # print('we made it here')
388
- # print(i)
389
- # cols.remove(i)
390
-
391
- # df_style_bang = top_d_score.head(10).style.background_gradient(cmap=co, subset=['L'+str(n_1)+' PP%','L'+str(n_2)+' PP%','L'+str(n_3)+' PP%','Roster%']).hide_index().set_properties(**{'Height': '12px'},**{'text-align': 'center'}).set_table_styles([{
392
- # 'selector': 'caption',
393
- # 'props': [
394
- # ('color', ''),
395
- # ('fontname', 'Century Gothic'),
396
- # ('font-size', '20px'),
397
- # ('font-style', 'italic'),
398
- # ('font-weight', ''),
399
- # ('text-align', 'centre'),
400
- # ]
401
-
402
- # },{'selector' :'th', 'props':[('text-align', 'center'),('Height','5px')]},{'selector' :'td', 'props':[('text-align', 'center'),('font-size', '13px'),('fontname', 'Century Gothic')]}]).format(
403
- # {'L'+str(n_1)+' PP%': '{:.0%}',
404
- # 'L'+str(n_2)+' PP%': '{:.0%}',
405
- # 'L'+str(n_3)+' PP%': '{:.0%}',
406
- # 'Roster%': '{:.0%}',
407
- # },)
408
-
409
- df_style_bang = top_d_score[cols].head(input.top_n()).style.background_gradient(cmap=co,vmin=0,vmax=1, subset=[x for x in cols if x.endswith('PP%')]).set_properties(**{'border': '3 px'},overwrite=False).set_table_styles([{
410
- 'selector': 'caption',
411
- 'props': [
412
- ('color', ''),
413
- ('fontname', 'Century Gothic'),
414
- ('font-size', '20px'),
415
- ('font-style', 'italic'),
416
- ('font-weight', ''),
417
- ('text-align', 'centre'),
418
- ]
419
-
420
- },{'selector' :'th', 'props':[('text-align', 'center'),('Height','px'),('color','black'),(
421
- 'border', '1px black solid !important')]},{'selector' :'td', 'props':[('text-align', 'center'),('font-size', '18px'),('color','black')]}],overwrite=False).set_properties(
422
- **{'background-color':'White','index':'White','min-width':'100px'},overwrite=False).set_properties(
423
- **{'background-color':'White','index':'White','min-width':'200px'},overwrite=False,subset=cols[0]).set_table_styles(
424
- [{'selector': 'th:first-child', 'props': [('background-color', 'white')]}],overwrite=False).set_table_styles(
425
- [{'selector': 'tr:first-child', 'props': [('background-color', 'white')]}],overwrite=False).set_table_styles(
426
- [{'selector': 'tr', 'props': [('line-height', '35px')]}],overwrite=False).set_properties(
427
- **{'Height': '35px'},**{'text-align': 'center'},overwrite=False).set_properties(**{'border': '3 px','color':'black'},overwrite=False).set_properties(**{'border': '3 px','color':'black'},overwrite=False).set_properties(
428
- **{'border': '1px black solid !important'},subset = ((list(top_d_score.index[:]),top_d_score.columns[:]))).set_properties(**{
429
- 'color': 'black'},overwrite=False).set_properties(
430
- **{'border': '1px black solid !important'},subset = ((list(top_d_score.index[:]),top_d_score.columns[:]))).format(
431
- {
432
- 'L'+str(n_1)+' PP%': '{:.0%}',
433
- 'L'+str(n_2)+' PP%': '{:.0%}',
434
- 'L'+str(n_3)+' PP%': '{:.0%}',
435
- 'Roster%': '{:.0%}',
436
- },).background_gradient(cmap=co, subset=[x for x in cols if x.endswith('PP%')]).hide_index()
437
-
438
- return df_style_bang
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
439
 
440
 
441
 
 
6
  import matplotlib.pyplot as plt
7
  from matplotlib.pyplot import figure
8
  from matplotlib.offsetbox import OffsetImage, AnnotationBbox
 
9
  import matplotlib.lines as mlines
10
  import matplotlib.transforms as mtransforms
11
  import numpy as np
 
30
  sns.set_context("notebook")
31
  import warnings
32
  warnings.filterwarnings('ignore')
33
+
 
 
 
 
 
 
34
  # import dataframe_image as dfi
35
  # from google.colab import drive
36
  def percentile(n):
 
55
  # import matplotlib.colors as mcolors
56
  # from matplotlib.ticker import FuncFormatter
57
  # from matplotlib.font_manager import FontProperties
58
+ import matplotlib.ticker as mtick
59
  import numpy as np
60
  # import matplotlib.pyplot as plt
61
  import matplotlib.colors
62
 
63
+ import matplotlib.pyplot as plt
64
+ from matplotlib.colors import Normalize
65
+ from matplotlib import cm
66
+ from datetime import date
67
+
68
+ def show_values(axs, orient="v", space=-1,stat = [],rank_n=[]):
69
+ def _single(ax):
70
+ if orient == "v":
71
+ i = 0
72
+ for p in ax.patches:
73
+
74
+ _x = p.get_x() + p.get_width() / 2
75
+ _y = p.get_y() + p.get_height() + (p.get_height()*0.01)
76
+ value = '{:.0f}'.format(p.get_height())
77
+ if isinstance(stat[i], float):
78
+ value_stat = '{:.2f}'.format(stat[i])
79
+ else:
80
+ value_stat = stat[i]
81
+ rank = rank_n[i]
82
+ ax.text(_x, -3.8, value_stat, ha="center",fontstyle='italic')
83
+ ax.text(_x, -4.2, rank, ha="center",fontstyle='italic')
84
+ i = i+1
85
+ elif orient == "h":
86
+ for p in ax.patches:
87
+ _x = p.get_x() + p.get_width() + float(space)
88
+ _y = p.get_y() + p.get_height() - (p.get_height()*0.5)
89
+ value = '{:.0f}'.format(p.get_width())
90
+ ax.text(_x, _y, value, ha="left")
91
+
92
+ if isinstance(axs, np.ndarray):
93
+ for idx, ax in np.ndenumerate(axs):
94
+ _single(ax)
95
+ else:
96
+ _single(axs)
97
 
98
 
 
 
 
99
 
100
+ data_r = requests.get("https://pub-api-ro.fantasysports.yahoo.com/fantasy/v2/league/427.l.public;out=settings/players;position=ALL;start=0;count=1000;sort=rank_season;search=;out=percent_owned;out=auction_values,ranks;ranks=season;ranks_by_position=season;out=expert_ranks;expert_ranks.rank_type=projected_season_remaining/draft_analysis;cut_types=diamond;slices=last7days?format=json_f").json()
 
 
101
 
102
  total_list = []
103
 
 
119
  single_list.append(0)
120
  total_list.append(single_list)
121
 
122
+ df_2023 = pd.DataFrame(data=total_list,columns=['player_id','rank_value','full','first','last','average_pick', 'average_cost','display_position','editorial_team_abbr','percent_owned'])
123
 
124
+ df_2023['pos_new'] = ['D' if "D" in x else 'F' for x in df_2023['display_position']]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
 
126
+ player_games = pd.read_csv('Drive/player_games_cards.csv',index_col=[0]).sort_values(by='date')
127
+ summary_2023 = pd.read_csv('Drive/summary_2024.csv',index_col=[0])
128
+ summary_2022 = pd.read_csv('Drive/2022-23/summary_2023.csv',index_col=[0])
129
+ team_games = pd.read_csv('Drive/team_games.csv',index_col=[0])
130
+ nhl_logos = pd.read_csv("NHL Logos - NHL Logos.csv")
131
+ team_games = team_games.merge(right=nhl_logos[['Team Name','Team']],left_on=['team'],right_on=['Team Name'],how='left')
132
 
133
+ yahoo_to_nhl_df = pd.read_csv('yahoo_to_nhl.csv')
 
 
134
 
135
+ yahoo_to_nhl_df = yahoo_to_nhl_df.merge(df_2023)
136
+ summary_2023 = summary_2023.merge(yahoo_to_nhl_df,left_on='player_id',right_on='nhl_id',suffixes=['','_yahoo'],how='left')
 
 
 
137
 
138
+ summary_2023 = summary_2023.merge(right=player_games.drop_duplicates(subset=['player_id'],keep='last')[['player_id','Position','Team']],left_on=['player_id'],right_on=['player_id'],how='left')
 
 
 
139
 
140
+ summary_2023.loc[summary_2023.display_position.isna(),'display_position'] = summary_2023.loc[summary_2023.display_position.isna(),'Position']
141
+ summary_2023.display_position = summary_2023.display_position.replace({'L':'LW','R':'RW'})
142
+ summary_2023.percent_owned = summary_2023.percent_owned.fillna(0)
143
 
144
+ player_games['game'] = player_games.groupby(['player_id']).cumcount() + 1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
 
146
+ skater_dict = summary_2023.set_index('player_id').sort_values(by='Player')
147
+ skater_dict['skater_team'] = skater_dict.Player + ' - ' + skater_dict.Team
148
+ skater_dict = skater_dict['skater_team'].to_dict()
149
 
150
  from shiny import ui, render, App
151
  import matplotlib.image as mpimg
 
156
 
157
  ui.panel_sidebar(
158
  #ui.input_date_range("date_range_id", "Date range input",start = statcast_df.game_date.min(), end = statcast_df.game_date.max()),
159
+ ui.input_select("id", "Select Skater",skater_dict,width=1),
160
+ ui.input_numeric("last_game_id", "Select Last 'n' Games",value=1,width=1),
 
 
 
 
161
  #ui.input_select("ignore_id", "Remove Columns",['Position','Roster%'],multiple=True,selectize=True),
162
+ width=2),
163
+ ui.panel_main(
164
+ ui.output_plot("plot",height = "1350px",width="2400px")
 
 
 
 
 
 
 
 
165
  )
166
  ),
167
  )
 
180
  #print(app_ui)
181
  def server(input, output, session):
182
 
 
 
 
 
 
 
183
  @output
184
+ @render.plot(alt="A histogram")
185
+ def plot():
186
+ # from matplotlib import rc, font_manager
187
+ # rc('text', usetex=True)
188
+ # rc('font',**{'family':'sans-serif','sans-serif':['Century Gothic']})
189
+ #fig.set_facecolor('white')
190
+ sns.set_theme(style="whitegrid", palette="pastel")
191
+ cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#4285F4","white","#FBBC04"])
192
 
193
+ player_id = int(input.id())
194
 
195
+ last_games = input.last_game_id()
196
 
197
 
198
 
199
+ player_games_one = player_games[player_games['player_id']==player_id].sort_values(by='game',ascending=False)
200
+
201
+ print(player_games_one)
202
+ summary_2023_one = summary_2023[summary_2023['player_id']==player_id]
203
+ summary_2022_one = summary_2022[summary_2022['player_id']==player_id]
204
+
205
+ last_games = min(last_games,summary_2023_one.GP.max())
206
+
207
+ name = player_games_one.Player.values[0]
208
+
209
+ df_last_games = pd.DataFrame(data={'Games':[last_games]})
210
+ df_last_games['TOI'] = player_games_one['TOI'][:last_games].sum()
211
+ df_last_games['TOI/G'] = player_games_one['TOI'][:last_games].sum()/df_last_games.Games
212
+ df_last_games['PP TOI/G'] = player_games_one['TOI_pp'][:last_games].sum()/df_last_games.Games
213
+ df_last_games['Points/60'] = player_games_one['Total Points'][:last_games].sum()/df_last_games.TOI*60
214
+ df_last_games['Shots/60'] = player_games_one['Shots'][:last_games].sum()/df_last_games.TOI*60
215
+ df_last_games['Hits/60'] = player_games_one['Hits'][:last_games].sum()/df_last_games.TOI*60
216
+ df_last_games['Blocks/60'] = player_games_one['Shots Blocked'][:last_games].sum()/df_last_games.TOI*60
217
+ df_last_games['Goals/60'] = player_games_one['Goals'][:last_games].sum()/df_last_games.TOI*60
218
+ df_last_games['ixG/60'] = player_games_one['ixG'][:last_games].sum()/df_last_games.TOI*60
219
+ df_last_games['G-ixG/60'] = df_last_games['Goals/60'] - df_last_games['ixG/60']
220
+ df_last_games['iCF/60'] = player_games_one['iCF'][:last_games].sum()/df_last_games.TOI*60
221
+ df_last_games['iSCF/60'] = player_games_one['iSCF'][:last_games].sum()/df_last_games.TOI*60
222
+ df_last_games['iHDCF/60'] = player_games_one['iHDCF'][:last_games].sum()/df_last_games.TOI*60
223
+ df_last_games['GF/60'] = player_games_one['GF'][:last_games].sum()/df_last_games.TOI*60
224
+ df_last_games['xGF/60'] = player_games_one['xGF'][:last_games].sum()/df_last_games.TOI*60
225
+ df_last_games['IPP'] = player_games_one['Total Points'][:last_games].sum()/player_games_one['GF'][:last_games].sum()
226
+ df_last_games['S%'] = player_games_one['Goals'][:last_games].sum()/player_games_one['Shots'][:last_games].sum()
227
+ df_last_games['xS%'] = player_games_one['ixG'][:last_games].sum()/player_games_one['Shots'][:last_games].sum()
228
+ df_last_games['1st Assist%'] = player_games_one['First Assists'][:last_games].sum()/player_games_one['Total Assists'][:last_games].sum()
229
+ df_last_games['Off. Zone Start%'] = player_games_one['Off.\xa0Zone Starts'][:last_games].sum()/(player_games_one['Off.\xa0Zone Starts'][:last_games].sum()+player_games_one['Def.\xa0Zone Starts'][:last_games].sum())
230
+ df_last_games['oiSH%'] = player_games_one['GF'][:last_games].sum()/player_games_one['SF'][:last_games].sum()
231
+ df_season = pd.DataFrame(data={'Games':[len(player_games_one)]})
232
+ df_season['TOI'] = player_games_one['TOI'][:len(player_games_one)].sum()
233
+ df_season['TOI/G'] = player_games_one['TOI'][:len(player_games_one)].sum()/df_season.Games
234
+ df_season['PP TOI/G'] = player_games_one['TOI_pp'][:len(player_games_one)].sum()/df_season.Games
235
+ df_season['Points/60'] = player_games_one['Total Points'][:len(player_games_one)].sum()/df_season.TOI*60
236
+ df_season['Shots/60'] = player_games_one['Shots'][:len(player_games_one)].sum()/df_season.TOI*60
237
+ df_season['Hits/60'] = player_games_one['Hits'][:len(player_games_one)].sum()/df_season.TOI*60
238
+ df_season['Blocks/60'] = player_games_one['Shots Blocked'][:len(player_games_one)].sum()/df_season.TOI*60
239
+ df_season['Goals/60'] = player_games_one['Goals'][:len(player_games_one)].sum()/df_season.TOI*60
240
+ df_season['ixG/60'] = player_games_one['ixG'][:len(player_games_one)].sum()/df_season.TOI*60
241
+ df_season['G-ixG/60'] = df_season['Goals/60'] - df_season['ixG/60']
242
+ df_season['iCF/60'] = player_games_one['iCF'][:len(player_games_one)].sum()/df_season.TOI*60
243
+ df_season['iSCF/60'] = player_games_one['iSCF'][:len(player_games_one)].sum()/df_season.TOI*60
244
+ df_season['iHDCF/60'] = player_games_one['iHDCF'][:len(player_games_one)].sum()/df_season.TOI*60
245
+ df_season['GF/60'] = player_games_one['GF'][:len(player_games_one)].sum()/df_season.TOI*60
246
+ df_season['xGF/60'] = player_games_one['xGF'][:len(player_games_one)].sum()/df_season.TOI*60
247
+ df_season['IPP'] = player_games_one['Total Points'][:len(player_games_one)].sum()/player_games_one['GF'][:len(player_games_one)].sum()
248
+ df_season['S%'] = player_games_one['Goals'][:len(player_games_one)].sum()/player_games_one['Shots'][:len(player_games_one)].sum()
249
+ df_season['xS%'] = player_games_one['ixG'][:len(player_games_one)].sum()/player_games_one['Shots'][:len(player_games_one)].sum()
250
+ df_season['1st Assist%'] = player_games_one['First Assists'][:len(player_games_one)].sum()/player_games_one['Total Assists'][:len(player_games_one)].sum()
251
+ df_season['Off. Zone Start%'] = player_games_one['Off.\xa0Zone Starts'][:len(player_games_one)].sum()/(player_games_one['Off.\xa0Zone Starts'][:len(player_games_one)].sum()+player_games_one['Def.\xa0Zone Starts'][:len(player_games_one)].sum())
252
+ df_season['oiSH%'] = player_games_one['GF'][:len(player_games_one)].sum()/player_games_one['SF'][:len(player_games_one)].sum()
253
+ df_last_games.rename(index={0:'Last '+str(df_last_games.Games[0])+' GP'},inplace=True)
254
+ df_season.rename(index={0:'2023-24 ('+str(df_season.Games[0])+'GP)'},inplace=True)
255
+
256
+ # cols_to_use = summary_all.columns.difference(summary_all_on_ice.columns)
257
+
258
+
259
+ # df_career_total = summary_all.merge(summary_all_on_ice, left_index=True, right_index=True,
260
+ # how='outer', suffixes=('', '_y'))
261
+
262
+ # df_career_total.drop(df_career_total.filter(regex='_y$').columns, axis=1, inplace=True)
263
+
264
+ # df_career_total = df_career_total.merge(summary_pp, left_index=True, right_index=True,
265
+ # how='outer', suffixes=('', '_y'))
266
+
267
+ # df_career_total.drop(df_career_total.filter(regex='_y$').columns, axis=1, inplace=True)
268
+
269
+ # df_career_total = df_career_total.merge(summary_pp_on_ice, left_index=True, right_index=True,
270
+ # how='outer', suffixes=('', '_y'))
271
+
272
+ # df_career_total.drop(df_career_total.filter(regex='_y$').columns, axis=1, inplace=True)
273
+ df_career_total = summary_2022_one.sort_index(ascending=False)
274
+ df_career_total.columns = [c.replace(u"\xa0", u" ") for c in list(df_career_total.columns)]
275
+ df_career = pd.DataFrame(data={'Games':[df_career_total.GP.sum()]})
276
+ df_career['TOI'] = df_career_total['TOI'].sum()
277
+ df_career['TOI/G'] = df_career_total['TOI'].sum()/df_career.Games
278
+ df_career['PP TOI/G'] = df_career_total['TOI_pp'].sum()/df_career.Games
279
+ df_career['Points/60'] = df_career_total['Total_Points'].sum()/df_career_total.TOI.sum()*60
280
+ df_career['Shots/60'] = df_career_total['Shots'].sum()/df_career_total.TOI.sum()*60
281
+ df_career['Hits/60'] = df_career_total['Hits'].sum()/df_career_total.TOI.sum()*60
282
+ df_career['Blocks/60'] = df_career_total['Shots_Blocked'].sum()/df_career_total.TOI.sum()*60
283
+ df_career['Goals/60'] = df_career_total['Goals'].sum()/df_career_total.TOI.sum()*60
284
+ df_career['ixG/60'] = df_career_total['ixG'].sum()/df_career_total.TOI.sum()*60
285
+ df_career['G-ixG/60'] = df_career['Goals/60'] - df_career['ixG/60']
286
+ df_career['iCF/60'] = df_career_total['iCF'].sum()/df_career_total.TOI.sum()*60
287
+ df_career['iSCF/60'] = df_career_total['iSCF'].sum()/df_career_total.TOI.sum()*60
288
+ df_career['iHDCF/60'] = df_career_total['iHDCF'].sum()/df_career_total.TOI.sum()*60
289
+ df_career['GF/60'] = df_career_total['GF'].sum()/df_career_total.TOI.sum()*60
290
+ df_career['xGF/60'] = df_career_total['xGF'].sum()/df_career_total.TOI.sum()*60
291
+ df_career['IPP'] = df_career_total['Total_Points'].sum()/df_career_total['GF'].sum()
292
+ df_career['S%'] = df_career_total['Goals'].sum()/df_career_total['Shots'].sum()
293
+ df_career['xS%'] = df_career_total['ixG'].sum()/df_career_total['Shots'].sum()
294
+ df_career['1st Assist%'] = df_career_total['First_Assists'].sum()/df_career_total['Assists'].sum()
295
+ df_career['Off. Zone Start%'] = df_career_total['OZ Start%'].sum()
296
+ df_career['oiSH%'] = df_career_total['GF'].sum()/df_career_total['SF'].sum()
297
+ df_career.rename(index={0:'2022-23 ('+str(df_career.Games[0])+'GP)'},inplace=True)
298
+ df_combined = df_last_games.append([df_season,df_career])
299
+ df_combined_t = round(df_combined,3).transpose()
300
+ df_combined.style.format(formatter={"IPP": "{:.1%}","S%": "{:.1%}","1st Assist%": "{:.1%}","Off. Zone Start%": "{:.1%}","oiSH%": "{:.1%}"}).set_precision(2)
301
+ rows = [idx for idx in df_combined_t.index if '/' not in idx]
302
+
303
+
304
+ df_combined_t = df_combined_t.astype(float).fillna(0)
305
+ # df_combined_t_style = df_combined_t.style.set_table_styles([{
306
+ # 'selector': 'caption',
307
+ # 'props': [
308
+ # ('color', ''),
309
+ # ('fontname', 'Century Gothic'),
310
+ # ('font-size', '12px'),
311
+ # ('font-style', 'italic'),
312
+ # ('font-weight', ''),
313
+ # ('text-align', 'centre'),
314
+ # ]
315
+
316
+ # },{'selector' :'th', 'props':[('text-align', 'center'),('Height','8px')]},{'selector' :'td', 'props':[('text-align', 'center'),('font-size', '10px')]}],overwrite=False).set_properties(
317
+ # **{'background-color':'White','index':'White','min-width':'60px'},overwrite=False).set_table_styles(
318
+ # [{'selector': 'th:first-child', 'props': [('background-color', 'white')]}],overwrite=False).set_table_styles(
319
+ # [{'selector': 'tr:first-child', 'props': [('background-color', 'white')]}],overwrite=False).set_table_styles(
320
+ # [{'selector': 'tr', 'props': [('line-height', '18px')]}],overwrite=False).set_properties(
321
+ # **{'Height': '8px'},**{'text-align': 'center'},overwrite=False).apply(
322
+
323
+ # lambda x: ["background: #FEEFC1" if (i < 1 and v > x.iloc[1]*1.05) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
324
+ # lambda x: ["background: #FEEFC1" if (i == 1 and v > x.iloc[2]*1.05) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
325
+ # lambda x: ["background: #D0E1FD" if (i < 1 and v < x.iloc[1]*0.95) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
326
+ # lambda x: ["background: #D0E1FD" if (i == 1 and v < x.iloc[2]*0.95) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
327
+ # lambda x: ["background: #FDDE82" if (i < 1 and v > x.iloc[1]*1.1) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
328
+ # lambda x: ["background: #FDDE82" if (i == 1 and v > x.iloc[2]*1.1) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
329
+ # lambda x: ["background: #A1C2FA" if (i < 1 and v < x.iloc[1]*0.9) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
330
+ # lambda x: ["background: #A1C2FA" if (i == 1 and v < x.iloc[2]*0.9) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
331
+ # lambda x: ["background: #FCCD43" if (i < 1 and v > x.iloc[1]*1.15) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
332
+ # lambda x: ["background: #FCCD43" if (i == 1 and v > x.iloc[2]*1.15) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
333
+ # lambda x: ["background: #72A4F7" if (i < 1 and v < x.iloc[1]*0.85) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
334
+ # lambda x: ["background: #72A4F7" if (i == 1 and v < x.iloc[2]*0.85) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
335
+ # lambda x: ["background: #FBBC04" if (i < 1 and v > x.iloc[1]*1.2) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
336
+ # lambda x: ["background: #FBBC04" if (i == 1 and v > x.iloc[2]*1.2) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
337
+ # lambda x: ["color: #ffffff" if (i < 1 and v < x.iloc[1]*0.8) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
338
+ # lambda x: ["color: #ffffff" if (i == 1 and v < x.iloc[2]*0.8) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
339
+ # lambda x: ["background: #4285F4" if (i == 0 and v < x.iloc[1]*0.8) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
340
+ # lambda x: ["background: #4285F4" if (i == 1 and v < x.iloc[2]*0.8) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
341
+ # lambda x: ["background: #ffffff" if (i == 0 and v == x.iloc[1]) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
342
+ # lambda x: ["background: #ffffff" if (i == 1 and v == x.iloc[2]) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
343
+ # lambda x: ["color: #000000" if (i < 1 and v == x.iloc[1]) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).apply(
344
+ # lambda x: ["color: #000000" if (i == 1 and v == x.iloc[2]) else "" for i,v in enumerate(x)], axis = 1,subset = (list(df_combined_t.index[2:]), list(df_combined_t.columns))).format(
345
+ # "{:.1%}",subset=(rows[2:],df_combined_t.columns)).format(
346
+ # '{:.0f}',subset=(rows[0],df_combined_t.columns)).set_precision(2).set_properties(
347
+ # **{'index':'White','min-width':'60px'},overwrite=False)
348
+
349
+
350
+
351
+ # #.set_table_styles([index_names, headers])
352
+
353
+ # df_combined_t_style = df_combined_t_style.format(
354
+ # {df_combined_t_style.columns[0]: '{:,.1%}'.format,
355
+ # df_combined_t_style.columns[1]: '{:,.1%}'.format,
356
+ # df_combined_t_style.columns[2]: '{:,.1%}'.format},subset=(rows[2:],df_combined_t.columns)
357
+ # )
358
+ # df_combined_t_style = df_combined_t_style.format(
359
+ # '{:.0f}',subset=(rows[0],df_combined_t.columns))
360
 
 
 
 
 
361
 
362
+ # df_combined_t_style
 
363
 
 
 
364
 
 
 
365
 
 
 
 
 
 
 
 
 
 
 
 
366
 
367
+ # dfi.export(df_combined_t_style, 'players/'+name+'_'+str(last_games)+'.png',fontsize=9,dpi=600,table_conversion='chrome')
368
+
369
+
370
+ percent_owned = summary_2023_one['percent_owned'].reset_index(drop=True)[0]
371
+ yahoo_position = summary_2023_one['display_position'].reset_index(drop=True)[0]
372
+
373
+
374
+
375
+ # image = "https://cms.nhl.bamgrid.com/images/headshots/current/168x168/"+str(player_id)+".png"
376
+ # logo = nhl_logos[nhl_logos.Team==list(player_games_one['Team'])[0]].reset_index().URL[0]
377
+ # fig, ax = plt.subplots(figsize=(10,16))
378
+ # fig.set_facecolor('white')
379
+
380
+ # # img = mpimg.imread('players/'+name+'_'+str(last_games)+'.png')
381
+ # # ax.imshow(img)
382
+ # # ax.axis('off')
383
+ # # fig.tight_layout()
384
+
385
+ # ax.axis('off')
386
+ # im = plt.imread('players/'+name+'_'+str(last_games)+'.png')
387
+ # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
388
+ # ax.imshow(im)
389
+ # ax.axis('off')
390
+ # fig.tight_layout()
391
+
392
+ # fig.text(x=0.5,y=-0.05,s='Note: Last Games compares to 2023-24. 2023-24 compares to 2022-23.',horizontalalignment='center',fontsize=16,fontname='Century Gothic')
393
+ # # fig.text(x=0.05,y=-0.1,s='Created By: @TJStats',horizontalalignment='left',fontsize=24,fontname='Century Gothic')
394
+ # # fig.text(x=0.95,y=-0.1,s='Data: Natural Stat Trick',horizontalalignment='right',fontsize=24,fontname='Century Gothic')
395
+ # fig.text(x=0.5,y=1.13,s='NHL Player Summary',horizontalalignment='center',fontsize=52, fontweight='bold')
396
+ # fig.text(x=0.5,y=1.08,s='2023-24 Season',horizontalalignment='center',fontsize=36,fontname='Century Gothic', fontstyle='italic')
397
+ # fig.text(x=0.12,y=1.03,s='Player',horizontalalignment='center',fontsize=22,fontname='Century Gothic', fontweight='bold')
398
+ # fig.text(x=0.12,y=1.0,s='Team',horizontalalignment='center',fontsize=22,fontname='Century Gothic', fontweight='bold')
399
+ # fig.text(x=0.12,y=0.97,s='Position',horizontalalignment='center',fontsize=22,fontname='Century Gothic', fontweight='bold')
400
+ # #fig.text(x=0.12,y=0.94,s='Age',horizontalalignment='center',fontsize=22,fontname='Century Gothic', fontweight='bold')
401
+ # # fig.text(x=0.12,y=0.91,s='Cap Hit',horizontalalignment='center',fontsize=22,fontname='Century Gothic', fontweight='bold')
402
+ # #fig.text(x=0.12,y=0.88,s='Roster%',horizontalalignment='center',fontsize=22,fontname='Century Gothic', fontweight='bold')
403
+
404
+ # fig.text(x=0.25,y=1.03,s=name,horizontalalignment='left',fontsize=22,fontname='Century Gothic')
405
+ # fig.text(x=0.25,y=1.0,s=list(player_games_one['Team'])[0],horizontalalignment='left',fontsize=22,fontname='Century Gothic')
406
+ # fig.text(x=0.25,y=0.97,s=yahoo_position,horizontalalignment='left',fontsize=22,fontname='Century Gothic')
407
+ # #fig.text(x=0.25,y=0.94,s=str(int(summary_2023_one.reset_index().AGE[0])),horizontalalignment='left',fontsize=22,fontname='Century Gothic')
408
+ # # fig.text(x=0.25,y=0.91,s=summary_2023_one.loc[summary_2023_one['player_id']==player_id].reset_index()['sheets'][0],horizontalalignment='left',fontsize=22,fontname='Century Gothic')
409
+ # #fig.text(x=0.25,y=0.88,s=str(int(percent_owned*100))+'%',horizontalalignment='left',fontsize=22,fontname='Century Gothic')
410
+
411
+
412
+ # im = plt.imread(image)
413
+ # newax = fig.add_axes([0.5,0.8,0.22,0.22], anchor='NW', zorder=1)
414
+ # newax.imshow(im)
415
+
416
+ # imr = plt.imread(logo)
417
+ # newerax = fig.add_axes([0.75,0.8,0.22,0.22], anchor='NW', zorder=1)
418
+ # newerax.imshow(imr)
419
+
420
+ # newax.axis('off')
421
+ # newerax.axis('off')
422
+
423
+ # plt.savefig('players/'+name+"_"+str(last_games)+' int.png',bbox_inches="tight")
424
+ # plt.close()
425
+
426
+ #test.loc[name == test.Player].reset_index().TOI[0]/1.5
427
+ min_time = min(math.floor(summary_2023.loc[player_id == summary_2023.player_id].reset_index().TOI[0]/100)*100,summary_2023.GP.max()*10)
428
+ # min_time = min(math.floor(test.loc[name == test.Player].reset_index().TOI[0]/100)*100,test.GP.max()*10)
429
+ test_filter = summary_2023[(summary_2023.TOI >= min_time)&(summary_2023.pos == summary_2023.loc[name == summary_2023.Player].reset_index().pos[0])]
430
+ test_filter['Goals/GP'] = test_filter['Goals']/test_filter['GP']
431
+ test_filter['Total Assists/GP'] = test_filter['Assists']/test_filter['GP']
432
+ test_filter['Total Points/GP'] = test_filter['Total_Points']/test_filter['GP']
433
+ test_filter['PP Points/GP'] = test_filter['Total_Points_pp']/test_filter['GP']
434
+ test_filter['Shots/GP'] = test_filter['Shots']/test_filter['GP']
435
+ test_filter['Hits/GP'] = test_filter['Hits']/test_filter['GP']
436
+ test_filter['Shots Blocked/GP'] = test_filter['Shots_Blocked']/test_filter['GP']
437
+ test_filter['ixG/60'] = test_filter['ixG']/test_filter['TOI']*60
438
+ test_filter['Goals/60'] = test_filter['Goals']/test_filter['TOI']*60
439
+ test_filter['G-xG/60'] = test_filter['G-ixG']/test_filter['TOI']*60
440
+ test_filter['iCF/60'] = test_filter['iCF']/test_filter['TOI']*60
441
+ test_filter['iSCF/60'] = test_filter['iSCF']/test_filter['TOI']*60
442
+ test_filter['First Assists/60'] = test_filter['First_Assists']/test_filter['TOI']*60
443
+ test_filter['Total Points/60'] = test_filter['Total_Points']/test_filter['TOI']*60
444
+
445
+
446
+ test_filter['G-xG/60'] = test_filter['Goals/60'] - test_filter['ixG/60']
447
+ test_filter['Goals Z-Score'] = (test_filter['Goals/GP']-test_filter['Goals/GP'].mean())/test_filter['Goals/GP'].std()
448
+ test_filter['Assists Z-Score'] = (test_filter['Total Assists/GP']-test_filter['Total Assists/GP'].mean())/test_filter['Total Assists/GP'].std()
449
+ test_filter['Points Z-Score'] = (test_filter['Total Points/GP']-test_filter['Total Points/GP'].mean())/test_filter['Total Points/GP'].std()
450
+ test_filter['PP Points Z-Score'] = (test_filter['PP Points/GP']-test_filter['PP Points/GP'].mean())/test_filter['PP Points/GP'].std()
451
+ test_filter['Shots Z-Score'] = (test_filter['Shots/GP']-test_filter['Shots/GP'].mean())/test_filter['Shots/GP'].std()
452
+ test_filter['Hits Z-Score'] = (test_filter['Hits/GP']-test_filter['Hits/GP'].mean())/test_filter['Hits/GP'].std()
453
+ test_filter['Blocks Z-Score'] = (test_filter['Shots Blocked/GP']-test_filter['Shots Blocked/GP'].mean())/test_filter['Shots Blocked/GP'].std()
454
+
455
+
456
+ test_filter['ixG Z-Score'] = (test_filter['ixG/60']-test_filter['ixG/60'].mean())/test_filter['ixG/60'].std()
457
+ test_filter['G Z-Score'] = (test_filter['Goals/60']-test_filter['Goals/60'].mean())/test_filter['Goals/60'].std()
458
+ test_filter['G-xG Z-Score'] = (test_filter['G-xG/60']-test_filter['G-xG/60'].mean())/test_filter['G-xG/60'].std()
459
+ test_filter['iCF Z-Score'] = (test_filter['iCF/60']-test_filter['iCF/60'].mean())/test_filter['iCF/60'].std()
460
+ test_filter['iSCF Z-Score'] = (test_filter['iSCF/60']-test_filter['iSCF/60'].mean())/test_filter['iSCF/60'].std()
461
+ test_filter['First Assists Z-Score'] = (test_filter['First Assists/60']-test_filter['First Assists/60'].mean())/test_filter['First Assists/60'].std()
462
+ test_filter['P Z-Score'] = (test_filter['Total Points/60']-test_filter['Total Points/60'].mean())/test_filter['Total Points/60'].std()
463
+ values_1 = test_filter.loc[name == test_filter.Player][['Goals/GP','Total Assists/GP','Total Points/GP','PP Points/GP','Shots/GP','Hits/GP','Shots Blocked/GP']].reset_index(drop=True).loc[0]
464
+ values_2 = test_filter.loc[name == test_filter.Player][['ixG/60','Goals/60','G-xG/60','iCF/60','iSCF/60','First Assists/60','Total Points/60']].reset_index(drop=True).loc[0]
465
+ categories = [i[:-11]+'/GP' for i in test_filter.columns[-14:-7]]
466
+
467
+ #categories = [*categories]
468
+
469
+ player = list(np.around(test_filter.loc[name == test_filter.Player][test_filter.columns[-14:-7]].values.flatten().tolist()))
470
+
471
+ #player = [*player, player[0]]
472
+
473
+
474
+ label_loc = np.linspace(start=0, stop=2 * np.pi, num=len(player))
475
+
476
+ players_stats_all_on_filter = test_filter.copy()
477
+ players_stats_all_on_filter['GF/60'] = (players_stats_all_on_filter['GF'])/players_stats_all_on_filter['TOI']*60
478
+ players_stats_all_on_filter['xGF/60'] = (players_stats_all_on_filter['xGF'])/players_stats_all_on_filter['TOI']*60
479
+ players_stats_all_on_filter['CF/60'] = (players_stats_all_on_filter['CF'])/players_stats_all_on_filter['TOI']*60
480
+ # players_stats_all_on_filter['oiSH%'] = (players_stats_all_on_filter['On-Ice SH%']-players_stats_all_on_filter['On-Ice SH%'].mean())/players_stats_all_on_filter['On-Ice SH%'].std()
481
+ #players_stats_all_on_filter['OZ Start%'] = (players_stats_all_on_filter['CF']-players_stats_all_on_filter['CF'])/players_stats_all_on_filter['CF']
482
+ players_stats_all_on_filter['GF Z-Score'] = (players_stats_all_on_filter['GF/60']-players_stats_all_on_filter['GF/60'].mean())/players_stats_all_on_filter['GF/60'].std()
483
+ players_stats_all_on_filter['xGF Z-Score'] = (players_stats_all_on_filter['xGF/60']-players_stats_all_on_filter['xGF/60'].mean())/players_stats_all_on_filter['xGF/60'].std()
484
+ players_stats_all_on_filter['CF Z-Score'] = (players_stats_all_on_filter['CF/60']-players_stats_all_on_filter['CF/60'].mean())/players_stats_all_on_filter['CF/60'].std()
485
+ players_stats_all_on_filter['oiSH% Z-Score'] = (players_stats_all_on_filter['oiSH']-players_stats_all_on_filter['oiSH'].mean())/players_stats_all_on_filter['oiSH'].std()
486
+ players_stats_all_on_filter['OZ Start% Z-Score'] = (players_stats_all_on_filter['OZ Start%']-players_stats_all_on_filter['OZ Start%'].mean())/players_stats_all_on_filter['OZ Start%'].std()
487
+ categories_on = [i[:-8]+'/60' for i in players_stats_all_on_filter.columns[-5:]]
488
+ categories_on = ['GF/60', 'xGF/60', 'CF/60', 'oiSH', 'OZ Start%']
489
+ player_on = list(np.around(players_stats_all_on_filter.loc[name == test_filter.Player][players_stats_all_on_filter.columns[-5:]].values.flatten().tolist(),2))
490
+ categories_1 = [i[:-8]+'/GP' for i in test_filter.columns[-14:-7]]
491
+ categories_2 = [i[:-8]+'/60' for i in test_filter.columns[-7:]]
492
+ categories = categories_1+categories_2
493
+ categories[12] = '1A/60'
494
+ player = list(np.around(test_filter.loc[name == test_filter.Player][test_filter.columns[-14:]].values.flatten().tolist(),2))
495
+
496
+ # color_scheme = []
497
+ # for i in player:
498
+ # if i <= -2:
499
+ # color_scheme.append('#4285F4')
500
+ # if i > -2 and i <= -1:
501
+ # color_scheme.append('#A1C2FA')
502
+ # if i > -1 and i <= 0:
503
+ # color_scheme.append('#D0E1FD')
504
+ # if i > 0 and i <= 1:
505
+ # color_scheme.append('#FEEFC1')
506
+ # if i > 1 and i <= 2:
507
+ # color_scheme.append('#FDDE82')
508
+ # if i > 2:
509
+ # color_scheme.append('#FBBC04')
510
 
511
 
512
+ goals_above_expected = test_filter.loc[name == test_filter.Player]['Goals'] - test_filter.loc[name == test_filter.Player]['ixG']
513
+ goals_above_expected = test_filter.loc[name == test_filter.Player]['Goals'] - test_filter.loc[name == test_filter.Player]['ixG']
514
+
515
+ # color_scheme_on= []
516
+ # for i in player_on:
517
+ # if i <= -2:
518
+ # color_scheme_on.append('#4285F4')
519
+ # if i > -2 and i <= -1:
520
+ # color_scheme_on.append('#A1C2FA')
521
+ # if i > -1 and i <= 0:
522
+ # color_scheme_on.append('#D0E1FD')
523
+ # if i > 0 and i <= 1:
524
+ # color_scheme_on.append('#FEEFC1')
525
+ # if i > 1 and i <= 2:
526
+ # color_scheme_on.append('#FDDE82')
527
+ # if i > 2:
528
+ # color_scheme_on.append('#FBBC04')
529
+
530
+ fig = plt.figure(figsize=(24, 13.5),dpi=300)
531
+ fig.set_facecolor('white')
532
+
533
+ cmap_new = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#4285F4","white",'#FBBC04'])
534
+ colormap_new = plt.get_cmap(cmap_new)
535
+ norm_new = Normalize(vmin=-3, vmax=3)
536
+
537
+ color_scheme = [colormap_new(norm_new(x)) for x in player]
538
+ color_scheme_on = [colormap_new(norm_new(x)) for x in player_on]
539
+
540
+ players_stats_all_on_filter = players_stats_all_on_filter.rename(columns={'On-Ice SH%':'oiSH%','Off.\xa0Zone Start %':'OZ Start%'})
541
+ values_on = players_stats_all_on_filter.loc[name == test_filter.Player][['GF/60', 'xGF/60', 'CF/60', 'oiSH', 'OZ Start%']].reset_index(drop=True).loc[0]
542
+ position_player = summary_2023_one['pos'].reset_index().pos[0]
543
+ rank_1 = list(test_filter[values_1.index].rank(method='min',ascending=False).loc[name == test_filter.Player].reset_index(drop=True).astype(int).iloc[0])
544
+ rank_2 = list(test_filter[values_2.index].rank(method='min',ascending=False).loc[name == test_filter.Player].reset_index(drop=True).astype(int).iloc[0])
545
+ rank_3 = list(players_stats_all_on_filter[values_on.index].rank(method='min',ascending=False).loc[name == test_filter.Player].reset_index(drop=True).astype(int).iloc[0][categories_on])
546
+ #rank_3 = rank_3 + list(players_stats_all_on_filter[values_on.index].rank(method='first',ascending=True).loc[name == test.Player].reset_index(drop=False).astype(int).iloc[0][categories_on[3:5]])
547
 
548
+ values_on = [float(x) for x in values_on]
 
 
549
 
550
+ player_games_one = player_games_one.merge(right=team_games[['Team','pp_toi','date']],left_on=['Team','date'],right_on=['Team','date'],how='left').fillna(0)
551
+ y=(player_games_one.rolling(last_games).sum()['TOI_pp']/player_games_one.rolling(last_games).sum()['pp_toi'])[last_games:]
552
+ player_games_one = player_games_one.sort_values(by='date').reset_index(drop=True)
553
 
554
+ # fig, ([ax1,ax2],[ax3,ax4])= plt.subplots(nrows=2, ncols=2,figsize=(16,10))
 
 
555
 
 
 
 
556
 
 
 
 
557
 
558
+ colormap = plt.get_cmap(cmap)
 
 
559
 
560
+ value = 1
561
+ # Normalize the value
562
+ norm = Normalize(vmin=0.8, vmax=1.2)
563
+ normalized_value = norm(value)
564
 
565
+ col_3_colour = ['white']*len(df_combined_t)
566
+ col_2_colour = [colormap(norm(x)) for x in list(((df_combined_t[df_combined_t.columns[1]].values) / (df_combined_t[df_combined_t.columns[2]].values)))]
567
+ col_1_colour = [colormap(norm(x)) for x in list(((df_combined_t[df_combined_t.columns[0]].values) / (df_combined_t[df_combined_t.columns[1]].values)))]
568
+ colour_df = pd.DataFrame(data=[col_1_colour,col_2_colour,col_3_colour]).T.values
569
 
570
+ colour_df[[0],[0]] = 'white'
571
+ colour_df[[1],[0]] = 'white'
572
+ colour_df[[0],[1]] = 'white'
573
+ colour_df[[1],[1]] = 'white'
574
+ if df_combined_t.values[[10],[0]] < 0:
575
+ if df_combined_t.values[[10],[1]] < 0:
576
+ #cmap_flip = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#FBBC04","white","#4285F4"])
577
+ norm = Normalize(vmin=-1.2, vmax=-0.8)
578
+ colour_df[[10],[0]] = tuple(colormap(norm(-df_combined_t.values[[10],[0]] / df_combined_t.values[[10],[1]])))
579
 
580
+ if df_combined_t.values[[10],[1]] < 0:
581
+ if df_combined_t.values[[10],[2]] < 0:
582
+ #cmap_flip = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#FBBC04","white","#4285F4"])
583
+ norm = Normalize(vmin=-1.2, vmax=-0.8)
584
+ colour_df[[10],[1]] = tuple(colormap(norm(-df_combined_t.values[[10],[1]] / df_combined_t.values[[10],[2]])))
585
 
 
 
 
586
 
587
 
 
 
 
 
 
 
 
 
 
588
 
589
 
590
+ ax1 = plt.subplot(1,3,1)
591
+ ax2 = plt.subplot(3,3,2)
592
+ ax3 = plt.subplot(3,3,5)
593
+ ax4 = plt.subplot(3,3,8)
594
+ ax5 = plt.subplot(3,3,3)
595
+ ax6 = plt.subplot(3,3,6)
596
+ ax7 = plt.subplot(3,3,9)
597
+ #axbot = plt.subplot(3,1,1)
598
+ axes = [ax1, ax2, ax3, ax4, ax5,ax6,ax7]
599
+ # ax[0][0].axis('off')
600
+ # im = plt.imread('players/'+name+'_'+str(last_games)+' int.png')
601
+ # ax[0][0] = fig.add_axes([0,0,1,1], anchor='W', zorder=1)
602
+ # ax[0][0].imshow(im)
603
 
604
+
605
+ # ax[0][0].axis('off')
606
+ # ax[1][0].axis('off')
607
+ image = "https://cms.nhl.bamgrid.com/images/headshots/current/168x168/"+str(player_id)+".png"
608
+ logo = nhl_logos[nhl_logos.Team==list(player_games_one['Team'])[0]].reset_index().URL[0]
609
+ #im = plt.imread('players/'+name+'_'+str(last_games)+'.png')
610
+ #ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
611
+ #ax.imshow(im)
612
 
613
 
614
+ im = plt.imread(image)
615
+ im = OffsetImage(im, zoom=.75)
616
+ ab = AnnotationBbox(im, (0.69, 0.765), xycoords='axes fraction', box_alignment=(0.0,0.0),bboxprops={'edgecolor':'white'})
617
+ ax1.add_artist(ab)
618
+ # axim = fig.add_axes([0.25,0.76,0.12,0.12], anchor='NW', zorder=1)
619
+ # axim.imshow(im)
620
+ # axim.axis('off')
621
 
622
+ imr = plt.imread(logo)
623
+ imr = OffsetImage(imr, zoom=.1)
624
+ ab = AnnotationBbox(imr, (0.45, 0.765), xycoords='axes fraction', box_alignment=(0.0,0.0),bboxprops={'edgecolor':'white'})
625
+ ax1.add_artist(ab)
626
+ # axim = fig.add_axes([0.18,0.76,0.75,0.075], anchor='NW', zorder=1)
627
+ # axim.imshow(imr)
628
+ # axim.axis('off')
629
 
630
+ sub_value = 0.16
631
+ ax1.text(x=0.5,y=1.13-sub_value,s='NHL Player Summary',horizontalalignment='center',fontsize=36, fontweight='bold')
632
+ ax1.text(x=0.5,y=1.08-sub_value,s='2022-23 Season',horizontalalignment='center',fontsize=28,fontname='Century Gothic', fontstyle='italic')
633
+ ax1.text(x=0.05,y=1.04-sub_value,s='Player',horizontalalignment='center',fontsize=18,fontname='Century Gothic', fontweight='bold')
634
+ ax1.text(x=0.05,y=1.005-sub_value,s='Team',horizontalalignment='center',fontsize=18,fontname='Century Gothic', fontweight='bold')
635
+ ax1.text(x=0.05,y=0.97-sub_value,s='Position',horizontalalignment='center',fontsize=18,fontname='Century Gothic', fontweight='bold')
636
+ #ax1.text(x=0.1,y=0.94-sub_value,s='Age',horizontalalignment='center',fontsize=18,fontname='Century Gothic', fontweight='bold')
637
+ #ax1.text(x=0.12,y=0.91-sub_value,s='Cap Hit',horizontalalignment='center',fontsize=22,fontname='Century Gothic', fontweight='bold')
638
+ ax1.text(x=0.05,y=0.935-sub_value,s='Roster%',horizontalalignment='center',fontsize=18,fontname='Century Gothic', fontweight='bold')
639
 
640
+ ax1.text(x=0.175,y=1.04-sub_value,s=name,horizontalalignment='left',fontsize=18,fontname='Century Gothic')
641
+ ax1.text(x=0.175,y=1.005-sub_value,s=list(player_games_one['Team'])[0],horizontalalignment='left',fontsize=18,fontname='Century Gothic')
642
+ ax1.text(x=0.175,y=0.97-sub_value,s=yahoo_position,horizontalalignment='left',fontsize=18,fontname='Century Gothic')
643
+ #ax1.text(x=0.25,y=0.94-sub_value,s=str(summary_2023_one.reset_index().AGE[0]),horizontalalignment='left',fontsize=22,fontname='Century Gothic')
644
+ #ax1.text(x=0.25,y=0.91-sub_value,s=summary_2023_one.loc[summary_2023_one['player_id']==player_id].reset_index()['sheets'][0],horizontalalignment='left',fontsize=22,fontname='Century Gothic')
645
+ ax1.text(x=0.175,y=0.935-sub_value,s=str(int(percent_owned*100))+'%',horizontalalignment='left',fontsize=18,fontname='Century Gothic')
646
 
647
 
 
 
 
 
 
648
 
 
 
 
 
 
 
649
 
650
+ ax1.axis("off")
651
 
 
652
 
 
653
 
 
 
654
 
655
+
656
+ table = ax1.table(cellText=df_combined_t.values, colLabels=df_combined_t.columns,rowLabels=df_combined_t.index
657
+ , cellLoc='center',rowLoc='center', bbox=[0.15, 0.05, 0.8, 0.7],cellColours=colour_df)
658
+ #table.auto_set_font_size(True)
659
+ table.set_fontsize(20)
660
+ table.scale(1, 1.5)
661
+
662
+
663
+
664
+ format_col = df_combined_t[df_combined_t.columns[0]]
665
+ n_c = 0
666
+ for cell in table.get_celld().values():
667
+ if n_c < 1*3:
668
+ if cell.get_text().get_text() in format_col.astype(str).values:
669
+ cell.get_text().set_text('{:,.0f}'.format(float(cell.get_text().get_text())))
670
+ elif n_c < 16*3:
671
+ if cell.get_text().get_text() in format_col.astype(str).values:
672
+ cell.get_text().set_text('{:,.2f}'.format(float(cell.get_text().get_text())))
673
+ else:
674
+ if cell.get_text().get_text() in format_col.astype(str).values:
675
+ cell.get_text().set_text('{:,.1%}'.format(float(cell.get_text().get_text())))
676
+ n_c = n_c + 1
677
+
678
+
679
+ format_col = df_combined_t[df_combined_t.columns[1]]
680
+ n_c = 0
681
+ for cell in table.get_celld().values():
682
+ if n_c < 1*3:
683
+ if cell.get_text().get_text() in format_col.astype(str).values:
684
+ cell.get_text().set_text('{:,.0f}'.format(float(cell.get_text().get_text())))
685
+ elif n_c < 16*3:
686
+ if cell.get_text().get_text() in format_col.astype(str).values:
687
+ cell.get_text().set_text('{:,.2f}'.format(float(cell.get_text().get_text())))
688
+ else:
689
+ if cell.get_text().get_text() in format_col.astype(str).values:
690
+ cell.get_text().set_text('{:,.1%}'.format(float(cell.get_text().get_text())))
691
+ n_c = n_c + 1
692
+
693
+ format_col = df_combined_t[df_combined_t.columns[2]]
694
+ n_c = 0
695
+ for cell in table.get_celld().values():
696
+ if n_c < 1*3:
697
+ if cell.get_text().get_text() in format_col.astype(str).values:
698
+ cell.get_text().set_text('{:,.0f}'.format(float(cell.get_text().get_text())))
699
+ elif n_c < 16*3:
700
+ if cell.get_text().get_text() in format_col.astype(str).values:
701
+ cell.get_text().set_text('{:,.2f}'.format(float(cell.get_text().get_text())))
702
+ else:
703
+ if cell.get_text().get_text() in format_col.astype(str).values:
704
+ cell.get_text().set_text('{:,.1%}'.format(float(cell.get_text().get_text())))
705
+ n_c = n_c + 1
706
+
707
+ #ax1.text('')
708
+
709
+
710
+
711
+ # ax1.axis('off')
712
+ # img = mpimg.imread('players/'+name+'_'+str(last_games)+' int.png')
713
+
714
+ # im = plt.imread('players/'+name+'_'+str(last_games)+'.png')
715
+ # ax1 = fig.add_axes([0.03,0.,1,1], anchor='SW')
716
+ # ax1.imshow(im)
717
+
718
+ # ax1.imshow(img)
719
+ # ax1.axis('off')
720
+ # fig.tight_layout()
721
+
722
+
723
+
724
+ categories[0:7] = ['G/GP','A/GP','P/GP','PPP/GP','S/GP','Hits/GP','Blk/GP']
725
+ _ = sns.barplot(data=test_filter[test_filter.columns[56:63]],x=categories[0:7],y=player[0:7],palette=color_scheme[0:7],edgecolor='black',ax=ax2)
726
+
727
+ ax2.set_title("Individual Per Game Z-Score (vs "+position_player+", min. "+str(min_time)+' TOI)',fontsize=14,fontname='Century Gothic')
728
+
729
+
730
+ #plt.rcParams['xtick.color']='#333F4B'
731
+ #ax[0][1].set_prop_cycle(ytick.color='#333F4B')
732
+
733
+
734
+ ax2.set_ylabel('Z-Score', fontsize=15,fontname='Century Gothic')
735
+ #plt.ylabel('Z-Score', fontsize=15,fontname='Century Gothic')
736
+
737
+ #plt.xlabel('Percentile', fontsize=12, color = '#000000',fontname='Century Gothic')
738
+ #plt.tick_params(axis='x', which='both', labelsize=10,bottom=False,top=False)
739
+ ax2.set_ylim([-3, 3])
740
+ plt.style.use('classic')
741
+ show_values(ax2,stat = values_1,rank_n=rank_1)
742
+ ax2.grid(axis = 'y',linestyle = '-', linewidth = 0.5,alpha=0.3)
743
+
744
+ ax2.set_axisbelow(True)
745
+ #ax[1].hlines(y=0,xmin=0,xmax=len(player),color='black')
746
+
747
+
748
+ #plt.savefig('players/'+name+"_"+str(last_games)+'_Z.png')#,bbox_inches="tight")
749
+ # ax[1][0] = sns.barplot(data=test,x=categories,y=player,palette=color_scheme,edgecolor='black')
750
+ # show_values(ax2,stat = values)
751
+ # data_input = df_shots[(df_shots.shooterName==name) & (df_shots.event!='MISS')]
752
+ # sns.kdeplot(data=data_input, x=data_input["yCordAdjusted"]*-1, y=data_input["xCordAdjusted"],fill=True,thresh=0.4,cmap=cmap,ax=ax3)
753
+ # #sns.scatterplot(data=data_input, x=data_input["yCordAdjusted"]*-1, y=data_input["xCordAdjusted"], alpha=1,zorder=25,cmap='Blues',s=400,hue='shotType',palette="Set2")
754
+ # rink = NHLRink(rotation=270)
755
+ # #x, y = rink.convert_xy(x, y)
756
+ # rink.draw(ax=ax3,display_range='dzone')
757
+ # ax3.set_title(name+" Shooting Heat Map",fontsize=16,fontname='Century Gothic')
758
+ #plt.suptitle('NHL Shot Locations ', fontsize=32, y = 0.91)
759
+ #plt.title('All Shots', fontsize=16, y=1.02)
760
+ sns.barplot(x=categories[7:14],y=player[7:14],palette=color_scheme[7:14],edgecolor='black',ax=ax3)
761
+ ax3.set_title("Individual Rate Z-Score (vs "+position_player+", min. "+str(min_time)+' TOI)',fontsize=14,fontname='Century Gothic')
762
+ ax3.grid(axis = 'y',linestyle = '-', linewidth = 0.5,alpha=0.3)
763
+ ax3.set_ylim([-3, 3])
764
+ ax3.set_axisbelow(True)
765
+ ax3.set_ylabel('Z-Score', fontsize=15,fontname='Century Gothic')
766
+ #plt.rcParams['xtick.color']='#333F4B'
767
+ #ax[0][1].set_prop_cycle(ytick.color='#333F4B')
768
+
769
+
770
+ sns.barplot(x=categories_on,y=player_on,palette=color_scheme_on,edgecolor='black',ax=ax4)
771
+ ax4.set_ylim([-3, 3])
772
+ ax4.set_title("On-Ice All Situations Rate Z-Score (vs "+position_player+", min. "+str(min_time)+' TOI)',fontsize=14,fontname='Century Gothic')
773
+ ax4.set_axisbelow(True)
774
+ ax4.set_ylabel('Z-Score', fontsize=15,fontname='Century Gothic')
775
+ ax4.grid(axis = 'y',linestyle = '-', linewidth = 0.5,alpha=0.3)
776
+
777
+ ax2.set_ylabel('Z-Score', fontsize=15,fontname='Century Gothic')
778
+ show_values(ax3,stat = values_2,rank_n=rank_2)
779
+ values_on[3] = str(round(values_on[3]*100,1))+'%'
780
+ values_on[4] = str(round(values_on[4]*100,1))+'%'
781
+ show_values(ax4,stat = values_on,rank_n=rank_3)
782
+
783
+
784
+ ax2.text(-0.5, -3.8, '2023-24', ha="right",fontstyle='italic',zorder=1)
785
+ ax3.text(-0.5, -3.8, '2023-24', ha="right",fontstyle='italic')
786
+ ax4.text(-0.5, -3.8, '2023-24', ha="right",fontstyle='italic')
787
+
788
+
789
+ ax2.text(-0.5, -4.2, 'Rank (of '+str(len(test_filter))+")", ha="right",fontstyle='italic',zorder=100)
790
+ ax3.text(-0.5, -4.2, 'Rank(of '+str(len(test_filter))+")", ha="right",fontstyle='italic',zorder=100)
791
+ ax4.text(-0.5, -4.2, 'Rank (of '+str(len(test_filter))+")", ha="right",fontstyle='italic',zorder=100)
792
+
793
+
794
+ ax2.tick_params(axis='x', which='both', labelsize=12,bottom=False,top=False)
795
+ ax3.tick_params(axis='x', which='both', labelsize=12,bottom=False,top=False)
796
+ ax4.tick_params(axis='x', which='both', labelsize=12,bottom=False,top=False)
797
+
798
+ if summary_2023_one.GP.values[0] < 2:
799
+ line_text_value = 1
800
+ else:
801
+ line_text_value = last_games+0.5
802
+
803
+ if position_player == 'F':
804
+ ax5.hlines(y=18,xmin=0, xmax=100, color='black',linewidth=1,linestyles='--',alpha=0.5)
805
+ ax5.text(s="1st",y=18,x=line_text_value, color='black',fontsize=8,bbox=dict(facecolor='white', alpha=0.5, pad=1.0))
806
+ ax5.hlines(y=16,xmin=0, xmax=100, color='black',linewidth=1,linestyles='--',alpha=0.5)
807
+ ax5.text(s="2nd",y=16,x=line_text_value, color='black',fontsize=8,bbox=dict(facecolor='white', alpha=0.5, pad=1.0))
808
+ ax5.hlines(y=14,xmin=0, xmax=100, color='black',linewidth=1,linestyles='--',alpha=0.5)
809
+ ax5.text(s="3rd",y=14,x=line_text_value, color='black',fontsize=8,bbox=dict(facecolor='white', alpha=0.5, pad=1.0))
810
+ ax5.hlines(y=12,xmin=0, xmax=100, color='black',linewidth=1,linestyles='--',alpha=0.5)
811
+ ax5.text(s="4th",y=12,x=line_text_value, color='black',fontsize=8,bbox=dict(facecolor='white', alpha=0.5, pad=1.0))
812
+
813
+ if position_player == 'D':
814
+ ax5.hlines(y=23,xmin=0, xmax=100, color='black',linewidth=1,linestyles='--',alpha=0.5)
815
+ ax5.text(s="1st",y=23,x=line_text_value, color='black',fontsize=8,bbox=dict(facecolor='white', alpha=0.5, pad=1.0))
816
+ ax5.hlines(y=20,xmin=0, xmax=100, color='black',linewidth=1,linestyles='--',alpha=0.5)
817
+ ax5.text(s="2nd",y=20,x=line_text_value, color='black',fontsize=8,bbox=dict(facecolor='white', alpha=0.5, pad=1.0))
818
+ ax5.hlines(y=17,xmin=0, xmax=100, color='black',linewidth=1,linestyles='--',alpha=0.5)
819
+ ax5.text(s="3rd",y=17,x=line_text_value, color='black',fontsize=8,bbox=dict(facecolor='white', alpha=0.5, pad=1.0))
820
+
821
+
822
+ sns.lineplot(x=player_games_one.game,y=player_games_one.rolling(last_games,min_periods=last_games).mean()['TOI'],ax=ax5,color='#FFB000',linewidth = 2,label='TOI/GP',legend=False)
823
+
824
+
825
+
826
+
827
+ ax5.xaxis.set_major_locator(MaxNLocator(integer=True))
828
+ ax5.set_xlim([last_games, np.max(player_games_one.game)])
829
+ axn = ax5.twinx()
830
+ #sns.lineplot(x=game_log_pp.Game,y=game_log_pp.rolling(last_games).mean()['PP_TOI'],ax=axn,color='#DCAD23',linewidth = 2,label='PP TOI/GP',legend=False)
831
+ #ax5.set_ylim([min(math.floor(min(player_games_one.TOI)/5)*5,10), math.ceil(max((player_games_one.rolling(last_games).mean().fillna(0)['TOI']))/5)*5])
832
+ ax5.set_ylim([10,30])
833
+ ax5.grid(axis = 'x',linestyle = '-', linewidth = 0.5,alpha=0.3)
834
+ ax5.grid(axis = 'y',linestyle = '-', linewidth = 0.5,alpha=0.3)
835
+ ax5.set_title(str(last_games)+" Game Rolling Average - TOI and PP%",fontsize=14,fontname='Century Gothic')
836
+ ax5.set(xlabel='Game', ylabel='TOI/GP')
837
+ axn.set(xlabel='Game', ylabel='PP%')
838
+ axn.yaxis.set_major_formatter(mtick.PercentFormatter(1.0))
839
+ axn.set_ylim([0, 1])
840
+
841
+
842
+ sns.lineplot(x=player_games_one.game,y=(player_games_one.rolling(last_games).sum()['TOI_pp']/player_games_one.rolling(last_games).sum()['pp_toi']),ax=axn,color='#648FFF',linewidth = 2,label='PP%',legend=False)
843
+ #
844
+ handles, labels = [ax5.get_legend_handles_labels()[0]+axn.get_legend_handles_labels()[0]]+[ax5.get_legend_handles_labels()[1]+axn.get_legend_handles_labels()[1]]
845
+ ax5.legend(handles, labels, fontsize=10,ncol=2,loc=9)
846
+
847
+ sns.lineplot(x=player_games_one.game,y=player_games_one.rolling(last_games).mean()['Total Points'],ax=ax6,color='#FFB000',label='Points',linewidth = 2)
848
+ sns.lineplot(x=player_games_one.game,y=player_games_one.rolling(last_games).mean()['Total Points_pp'],ax=ax6,color='#648FFF',label='PP Points',linewidth = 2)
849
+ sns.lineplot(x=player_games_one.game,y=player_games_one.rolling(last_games).mean()['Goals'],ax=ax6,color='#DC267F',label='Goals',linewidth = 2)
850
+ sns.lineplot(x=player_games_one.game,y=player_games_one.rolling(last_games).mean()['Total Assists'],ax=ax6,color='#FE6100',label='Assists',linewidth = 2)
851
+ ax6.legend(fontsize=10,ncol=4,loc=9)
852
+ ax6.xaxis.set_major_locator(MaxNLocator(integer=True))
853
+ ax6.set_xlim([last_games, np.max(player_games_one.game)])
854
+ ax6.set_ylim([0, round(max((player_games_one.rolling(last_games).mean().fillna(0)['Total Points'])+1)*2)/2])
855
+ ax6.grid(axis = 'x',linestyle = '-', linewidth = 0.5,alpha=0.3)
856
+ ax6.grid(axis = 'y',linestyle = '-', linewidth = 0.5,alpha=0.3)
857
+ ax6.set_title(str(last_games)+" Game Rolling Average - Points",fontsize=14)
858
+ ax6.set(xlabel='Game', ylabel='Value Per Game')
859
+
860
+
861
+ sns.lineplot(x=player_games_one.game,y=player_games_one.rolling(last_games).mean()['Shots'],ax=ax7,color='#FFB000',linewidth = 2,label='Shots')
862
+ sns.lineplot(x=player_games_one.game,y=player_games_one.rolling(last_games).mean()['iCF'],ax=ax7,color='#648FFF',linewidth = 2,label='iCF')
863
+ # sns.lineplot(x=player_games_one.game,y=player_games_one.rolling(last_games).mean()['iSCF'],ax=ax7,color='#DC267F',linewidth = 2,label='iSCF')
864
+ sns.lineplot(x=player_games_one.game,y=player_games_one.rolling(last_games).mean()['Hits'],ax=ax7,color='#DC267F',linewidth = 2,label='Hits')
865
+ sns.lineplot(x=player_games_one.game,y=player_games_one.rolling(last_games).mean()['Shots Blocked'],ax=ax7,color="#FE6100",linewidth = 2,label='Blocks')
866
+
867
+ ax7.legend(fontsize=10,ncol=5,loc=9)
868
+ ax7.xaxis.set_major_locator(MaxNLocator(integer=True))
869
+ ax7.set_xlim([last_games, np.max(player_games_one.game)])
870
+ ax7.set_ylim([0, max(round(max((player_games_one.rolling(last_games).mean().fillna(0)['iCF'])+1)*2)/2+1,round(max((player_games_one.rolling(last_games).mean().fillna(0)['Shots'])+1)*2)/2+1,round(max((player_games_one.rolling(last_games).mean().fillna(0)['Hits'])+1)*2)/2+1,round(max((player_games_one.rolling(last_games).mean().fillna(0)['Shots Blocked'])+1)*2)/2+1)])
871
+ ax7.grid(axis = 'x',linestyle = '-', linewidth = 0.5,alpha=0.3)
872
+ ax7.grid(axis = 'y',linestyle = '-', linewidth = 0.5,alpha=0.3)
873
+ ax7.set_title(str(last_games)+" Game Rolling Average - Shots and Bangers",fontsize=14,fontname='Century Gothic')
874
+ ax7.set(xlabel='Game', ylabel='Value Per Game')
875
+ ax2.hlines(y=0,xmin=-0.5, xmax=len(ax2.patches)-0.5, color='black',linewidth=1)
876
+ ax3.hlines(y=0,xmin=-0.5, xmax=len(ax3.patches)-0.5, color='black',linewidth=1)
877
+ ax4.hlines(y=0,xmin=-0.5, xmax=len(ax4.patches)-0.5, color='black',linewidth=1)
878
+
879
+ ax2.set_xlim([-0.5, len(ax2.patches)-0.5])
880
+ ax3.set_xlim([-0.5, len(ax3.patches)-0.5])
881
+ ax4.set_xlim([-0.5, len(ax4.patches)-0.5])
882
+
883
+ #plt.tight_layout(pad=5, w_pad=2, h_pad=2)
884
+
885
+ #abot = fig.add_axes([0.075,0.025,0.9,0.025], anchor='NW', zorder=1)
886
+
887
+ print('here')
888
+
889
+ ax1.text(x=0.0,y=-0.025,s='Created By: @TJStats',horizontalalignment='left',fontsize=14)#,fontname='Century Gothic')
890
+ ax1.text(x=0.0,y=-0.05,s='Data: Natural Stat Trick, CapFriendly, Yahoo Fantasy',horizontalalignment='left',fontsize=14)#,fontname='Century Gothic')
891
+ ax1.text(x=0.725,y=-0.025,s=f'Generated: {str(date.today())}',horizontalalignment='right',fontsize=14)#,fontname='Century Gothic')
892
+
893
+ from matplotlib.font_manager import FontProperties
894
+ font_properties_label = FontProperties(family='century gothic', size=16)
895
+ ax5.set_xlabel(xlabel=ax5.get_xlabel(),fontproperties=font_properties_label)
896
+ ax6.set_xlabel(xlabel=ax6.get_xlabel(),fontproperties=font_properties_label)
897
+ ax7.set_xlabel(xlabel=ax7.get_xlabel(),fontproperties=font_properties_label)
898
+ ax5.set_ylabel(ylabel=ax5.get_ylabel(),fontproperties=font_properties_label)
899
+ ax6.set_ylabel(ylabel=ax6.get_ylabel(),fontproperties=font_properties_label)
900
+ ax7.set_ylabel(ylabel=ax7.get_ylabel(),fontproperties=font_properties_label)
901
+
902
+ font_properties_title = FontProperties(family='century gothic', size=16)
903
+ ax2.set_title(label=ax2.get_title(),fontproperties=font_properties_title)
904
+ ax3.set_title(label=ax3.get_title(),fontproperties=font_properties_title)
905
+ ax4.set_title(label=ax4.get_title(),fontproperties=font_properties_title)
906
+ ax5.set_title(label=ax5.get_title(),fontproperties=font_properties_title)
907
+ ax6.set_title(label=ax6.get_title(),fontproperties=font_properties_title)
908
+ ax7.set_title(label=ax7.get_title(),fontproperties=font_properties_title)
909
+
910
+ ax1.text(x=0.43,y=0.025,s='Note: Last Games compares to 2023-24. 2023-24 compares to 2022-23.',horizontalalignment='center',fontsize=12,fontname='Century Gothic')
911
+ # font_properties_ticks = FontProperties(family='century gothic', size=12)
912
+ # ax5.set_xticklabels(ax5.get_xticks(),fontproperties=font_properties_label)
913
+
914
+ plt.xticks(fontname = 'century gothic')
915
+
916
+
917
+
918
+ #abot.axis('off')
919
+ #ax1.set_zorder(2)
920
+ fig.tight_layout()
921
+
922
+ # for i in range(0,len(df_combined_t.index)):
923
+ # ax1.text(s=df_combined_t.index[i],x=10,y=700+(10*i),fontsize=10,bbox=dict(facecolor='red', alpha=1))
924
+
925
+
926
+ # #plt.figure(dpi=300)
927
+ # if not os.path.exists('player_cards/skaters/'+name):
928
+ # os.makedirs('player_cards/skaters/'+name)
929
+
930
+ # dir = 'players/'
931
+ # for f in os.listdir(dir):
932
+ # os.remove(os.path.join(dir, f))
933
+
934
+
935
+ #plt.savefig('player_cards/skaters/'+name+'/'+name+"_"+str(last_games)+'_Znew.png',dpi=600,bbox_inches="tight")
936
+
937
+ #matplotlib.rcParams["figure.dpi"] = 600
938
+
939
+ #plt.savefig('players/'+name+"_"+str(last_games)+'_Znew.png',dpi=600,bbox_inches="tight")
940
 
941
 
942