import requests import pandas as pd import seaborn as sns import matplotlib.pyplot as plt from matplotlib.pyplot import figure from matplotlib.offsetbox import OffsetImage, AnnotationBbox from scipy import stats import matplotlib.lines as mlines import matplotlib.transforms as mtransforms import numpy as np import plotly.express as px #!pip install chart_studio # import chart_studio.tools as tls from bs4 import BeautifulSoup import matplotlib.pyplot as plt import numpy as np import matplotlib.font_manager as font_manager from datetime import datetime import pytz from datetime import date datetime.now(pytz.timezone('US/Pacific')).strftime('%B %d, %Y') # Configure Notebook #%matplotlib inline plt.style.use('fivethirtyeight') sns.set_context("notebook") import warnings warnings.filterwarnings('ignore') from urllib.request import urlopen import json from datetime import date, timedelta import dataframe_image as dfi from os import listdir from os.path import isfile, join import datetime import seaborn as sns import os import calendar from IPython.display import display, HTML import matplotlib.image as mpimg from skimage import io import difflib from datetime import datetime import pytz datetime.now(pytz.timezone('US/Pacific')).strftime('%B %d, %Y') # Configure Notebook #%matplotlib inline plt.style.use('fivethirtyeight') sns.set_context("notebook") import warnings warnings.filterwarnings('ignore') # import yfpy # from yfpy.query import YahooFantasySportsQuery # import yahoo_oauth import json import openpyxl from sklearn import preprocessing from PIL import Image import logging import matplotlib.patches as patches from matplotlib.patches import Rectangle from matplotlib.font_manager import FontProperties from matplotlib.offsetbox import OffsetImage, AnnotationBbox import requests import pickle import pandas as pd # # Loop over the counter and format the API call r = requests.get('https://statsapi.web.nhl.com/api/v1/schedule?startDate=2023-10-01&endDate=2024-06-01') schedule = r.json() def flatten(t): return [item for sublist in t for item in sublist] game_id = flatten([[x['gamePk'] for x in schedule['dates'][y]['games']] for y in range(0,len(schedule['dates']))]) game_date = flatten([[x['gameDate'] for x in schedule['dates'][y]['games']] for y in range(0,len(schedule['dates']))]) game_home = flatten([[x['teams']['home']['team']['name'] for x in schedule['dates'][y]['games']] for y in range(0,len(schedule['dates']))]) game_away = flatten([[x['teams']['away']['team']['name'] for x in schedule['dates'][y]['games']] for y in range(0,len(schedule['dates']))]) schedule_df = pd.DataFrame(data={'game_id': game_id, 'game_date' : game_date, 'game_home' : game_home, 'game_away' : game_away}) schedule_df.game_date = pd.to_datetime(schedule_df['game_date']).dt.tz_convert(tz='US/Eastern').dt.date schedule_df = schedule_df.replace('MontrĂ©al Canadiens','Montreal Canadiens') schedule_df.head() team_abv = pd.read_csv('team_abv.csv') yahoo_weeks = pd.read_csv('yahoo_weeks.csv') #yahoo_weeks['Number'] = yahoo_weeks['Number'].astype(int) yahoo_weeks['Start'] = pd.to_datetime(yahoo_weeks['Start']) yahoo_weeks['End'] = pd.to_datetime(yahoo_weeks['End']) yahoo_weeks.head(5) def highlight_cols(s): color = '#C2FEE9' return 'background-color: %s' % color def highlight_cells(val): color = 'white' if val == ' ' else '' return 'background-color: {}'.format(color) import matplotlib.pyplot as plt import matplotlib.colors cmap_total = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#56B4E9","#FFFFFF","#F0E442"]) cmap_off = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#FFFFFF","#F0E442"]) cmap_back = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#FFFFFF","#56B4E9"]) cmap_sum = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#FFFFFF","#F0E442"]) schedule_df = schedule_df.merge(right=team_abv,left_on='game_away',right_on='team_name',how='inner',suffixes=['','_away']) schedule_df = schedule_df.merge(right=team_abv,left_on='game_home',right_on='team_name',how='inner',suffixes=['','_home']) schedule_df['away_sym'] = '@' schedule_df['home_sym'] = 'vs' if not os.path.isfile('standings/standings_'+str(date.today())+'.csv'): standings_df_old = pd.read_html('https://www.hockey-reference.com/leagues/NHL_2023_standings.html')[0].append(pd.read_html('https://www.hockey-reference.com/leagues/NHL_2023_standings.html')[1]) standings_df_old.to_csv('standings/standings_'+str(date.today())+'.csv') standings_df_old = pd.read_csv('standings/standings_'+str(date.today())+'.csv',index_col=[0]) standings_df = standings_df_old[standings_df_old['Unnamed: 0'].str[-8:] != 'Division'].sort_values('Unnamed: 0').reset_index(drop=True).rename(columns={'Unnamed: 0':'Team'})#.drop(columns='Unnamed: 0') #standings_df = standings_df.replace('St. Louis Blues','St Louis Blues') standings_df['GF/GP'] = standings_df['GF'].astype(int)/standings_df['GP'].astype(int) standings_df['GA/GP'] = standings_df['GA'].astype(int)/standings_df['GP'].astype(int) standings_df['GF_Rank'] = standings_df['GF/GP'].rank(ascending=True,method='first')/10-1.65 standings_df['GA_Rank'] = standings_df['GA/GP'].rank(ascending=False,method='first')/10-1.65 standings_df.Team = standings_df.Team.str.strip('*') standings_df = standings_df.merge(right=team_abv,left_on='Team',right_on='team_name') schedule_stack = pd.DataFrame() schedule_stack['date'] = pd.to_datetime(list(schedule_df['game_date'])+list(schedule_df['game_date'])) schedule_stack['team'] = list(schedule_df['team_name'])+list(schedule_df['team_name_home']) schedule_stack['team_abv'] = list(schedule_df['team_abv'])+list(schedule_df['team_abv_home']) schedule_stack['symbol'] = list(schedule_df['away_sym'])+list(schedule_df['home_sym']) schedule_stack['team_opponent'] = list(schedule_df['team_name_home'])+list(schedule_df['team_name']) schedule_stack['team_abv_home'] = list(schedule_df['team_abv_home'])+list(schedule_df['team_abv']) schedule_stack = schedule_stack.merge(right=standings_df[['team_abv','GF_Rank']],left_on='team_abv',right_on='team_abv',how='inner',suffixes=("",'_y')) schedule_stack = schedule_stack.merge(right=standings_df[['team_abv','GA_Rank']],left_on='team_abv_home',right_on='team_abv',how='inner',suffixes=("",'_y')) schedule_stack = schedule_stack.merge(right=standings_df[['team_abv','GF_Rank']],left_on='team_abv',right_on='team_abv',how='inner',suffixes=("",'_y')) schedule_stack = schedule_stack.merge(right=standings_df[['team_abv','GA_Rank']],left_on='team_abv_home',right_on='team_abv',how='inner',suffixes=("",'_y')) list_o = schedule_stack.sort_values(['team','date'],ascending=[True,True]).reset_index(drop=True) new_list = [x - y for x, y in zip(list_o['date'][1:], list_o['date'])] b2b_list = [0] + [x.days for x in new_list] b2b_list = [1 if x==1 else 0 for x in b2b_list] test = list(schedule_stack.groupby(by='date').count()['team']) offnight = [1 if x<15 else 0 for x in test] offnight_df = pd.DataFrame({'date':schedule_stack.sort_values('date').date.unique(),'offnight':offnight}).sort_values('date').reset_index(drop=True) schedule_stack = schedule_stack.merge(right=offnight_df,left_on='date',right_on='date',how='right') schedule_stack = schedule_stack.sort_values(['team','date'],ascending=[True,True]).reset_index(drop=True) schedule_stack['b2b'] = b2b_list schedule_stack.date = pd.to_datetime(schedule_stack.date) away_b2b = [] home_b2b = [] for i in range(0,len(schedule_stack)): away_b2b.append(schedule_stack[(schedule_stack.date[i]==schedule_stack.date)&(schedule_stack.team_opponent[i]==schedule_stack.team)].reset_index(drop=True)['b2b'][0]) home_b2b.append(schedule_stack[(schedule_stack.date[i]==schedule_stack.date)&(schedule_stack.team[i]==schedule_stack.team)].reset_index(drop=True)['b2b'][0]) schedule_stack['away_b2b'] = away_b2b schedule_stack['home_b2b'] = home_b2b schedule_stack['away_b2b'] = schedule_stack['away_b2b'].replace(1,' 😴') schedule_stack['away_b2b'] = schedule_stack['away_b2b'].replace(0,'') schedule_stack.head() FontProperties(fname='/System/Library/Fonts/Apple Color Emoji.ttc') 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=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() total_list = [] for x in data_r['fantasy_content']['league']['players']: single_list = [] single_list.append(int(x['player']['player_id'])) single_list.append(int(x['player']['player_ranks'][0]['player_rank']['rank_value'])) single_list.append(x['player']['name']['full']) single_list.append(x['player']['name']['first']) single_list.append(x['player']['name']['last']) single_list.append(x['player']['draft_analysis']['average_pick']) single_list.append(x['player']['average_auction_cost']) single_list.append(x['player']['display_position']) single_list.append(x['player']['editorial_team_abbr']) if 'value' in x['player']['percent_owned']: single_list.append(x['player']['percent_owned']['value']/100) else: single_list.append(0) total_list.append(single_list) 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']) week_dict = yahoo_weeks.set_index('Number')['Week'].sort_index().to_dict() from shiny import ui, render, App import matplotlib.image as mpimg # app_ui = ui.page_fluid( # # ui.output_plot("plot"), # #ui.h2('MLB Batter Launch Angle vs Exit Velocity'), # ui.layout_sidebar( # ui.panel_sidebar( # ui.input_select("id", "Select Batter",batter_dict), # ui.input_select("plot_id", "Select Plot",{'scatter':'Scatter Plot','dist':'Distribution Plot'}))) # , # ui.panel_main(ui.output_plot("plot",height = "750px",width="1250px")), # #ui.download_button('test','Download'), # ) app_ui = ui.page_fluid(ui.layout_sidebar( # Available themes: # cerulean, cosmo, cyborg, darkly, flatly, journal, litera, lumen, lux, # materia, minty, morph, pulse, quartz, sandstone, simplex, sketchy, slate, # solar, spacelab, superhero, united, vapor, yeti, zephyr ui.panel_sidebar( ui.input_select("week_id", "Select Week (Set as Season for Custom Date Range)",week_dict,width=1), ui.input_select("sort_id", "Sort Column",['Score','Team','Total','Off-Night','B2B'],width=1), ui.input_switch("a_d_id", "Ascending?"), #ui.input_select("date_id", "Select Date",yahoo_weeks['Week'],width=1), ui.input_date_range("date_range_id", "Date range input",start = datetime.today().date(), end = datetime.today().date() + timedelta(days=6)), ui.output_table("result"),width=3), ui.panel_main(ui.tags.h3(""), ui.div({"style": "font-size:2em;"},ui.output_text("txt_title")), #ui.tags.h2("Fantasy Hockey Schedule Summary"), ui.tags.h5("Created By: @TJStats, Data: NHL"), ui.div({"style": "font-size:1.2em;"},ui.output_text("txt")), ui.output_table("schedule_result"), ui.tags.h5('Legend'), ui.output_table("schedule_result_legend"), ui.tags.h6('An Off Night is defined as a day in which less than half the teams in the NHL are playing'), ui.tags.h6('The scores are determined by using games played, off-nights, B2B, and strength of opponents') ) )) # ui.row( # ui.column( # 3, # ui.input_date("x", "Date input"),), # ui.column( # 1, # ui.input_select("level_id", "Select Level",level_dict,width=1)), # ui.column( # 3, # ui.input_select("stat_id", "Select Stat",plot_dict_small,width=1)), # ui.column( # 2, # ui.input_numeric("n", "Rolling Window Size", value=50)), # ), # ui.output_table("result_batters")), # ui.nav( # "Pitchers", # ui.row( # ui.column( # 3, # ui.input_select("id_pitch", "Select Pitcher",pitcher_dict,width=1,selected=675911), # ), # ui.column( # 1, # ui.input_select("level_id_pitch", "Select Level",level_dict,width=1)), # ui.column( # 3, # ui.input_select("stat_id_pitch", "Select Stat",plot_dict_small_pitch,width=1)), # ui.column( # 2, # ui.input_numeric("n_pitch", "Rolling Window Size", value=50)), # ), # ui.output_table("result_pitchers")), # ) # ) # ) from urllib.request import Request, urlopen # importing OpenCV(cv2) module def server(input, output, session): @output @render.text def txt(): week_set = int(input.week_id()) if week_set != 0: if pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]['Start'].values[0]).year != pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]['End'].values[0]).year: return f'{pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["Start"].values[0]).strftime("%B %d, %Y")} to {pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["End"].values[0]).strftime("%B %d, %Y")}' else: if pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["Start"].values[0]).month != pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["End"].values[0]).month: return f'{pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["Start"].values[0]).strftime("%B %d")} to {pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["End"].values[0]).strftime("%B %d, %Y")}' else: return f'{pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["Start"].values[0]).strftime("%B %d")} to {pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["End"].values[0]).strftime("%d, %Y")}' else: if input.date_range_id()[0].year != input.date_range_id()[1].year: return f'{input.date_range_id()[0].strftime("%B %d, %Y")} to {input.date_range_id()[1].strftime("%B %d, %Y")}' else: if input.date_range_id()[0].month != input.date_range_id()[1].month: return f'{input.date_range_id()[0].strftime("%B %d")} to {input.date_range_id()[1].strftime("%B %d, %Y")}' else: return f'{input.date_range_id()[0].strftime("%B %d")} to {input.date_range_id()[1].strftime("%d, %Y")}' @output @render.text def txt_title(): week_set = int(input.week_id()) if week_set != 0: return f'Fantasy Hockey Schedule Summary - Yahoo - Week {input.week_id()}' else: return f'Fantasy Hockey Schedule Summary' @output @render.table def result(): #print(yahoo_weeks) return yahoo_weeks @output @render.table def schedule_result(): week_set = int(input.week_id()) print(week_set) if week_set == 0: start_point = input.date_range_id()[0] end_point = input.date_range_id()[1] else: start_point = yahoo_weeks[yahoo_weeks.Number==week_set].reset_index(drop=True)['Start'][0] end_point = yahoo_weeks[yahoo_weeks.Number==week_set].reset_index(drop=True)['End'][0] sort_value='Score' ascend=False weekly_stack = schedule_stack[(schedule_stack['date'].dt.date>=start_point)&(schedule_stack['date'].dt.date<=end_point)] date_list = pd.date_range(start_point,end_point,freq='d') test_list = [[]] * len(date_list) for i in range(0,len(date_list)): test_list[i] = team_abv.merge(right=weekly_stack[weekly_stack['date']==date_list[i]],left_on='team_abv',right_on='team_abv',how='left') test_list[i] = test_list[i].fillna("") test_list[i]['new_text'] = test_list[i]['symbol'] + ' '+ test_list[i]['team_abv_home'] + test_list[i]['away_b2b'] test_df = pd.DataFrame() test_df['Team'] = list(team_abv['team_abv']) test_df['Total'] = test_df.merge(right=weekly_stack.groupby('team_abv')['team_abv'].apply(lambda x: x[x != ''].count()),left_on=['Team'],right_index=True,how='left').fillna(0)['team_abv'] test_df['Off-Night'] = test_df.merge(right=weekly_stack.groupby('team_abv').sum()['offnight'],left_on=['Team'],right_index=True,how='left').fillna(0)['offnight'] test_df['B2B']= test_df.merge(right=weekly_stack.groupby('team_abv').sum()['b2b'],left_on=['Team'],right_index=True,how='left').fillna(0)['b2b'] gf_rank = np.array(test_df.merge(right=weekly_stack.groupby('team_abv').mean()['GF_Rank'],left_on=['Team'],right_index=True,how='left').fillna(0)['GF_Rank']) ga_rank = np.array(test_df.merge(right=weekly_stack.groupby('team_abv').mean()['GA_Rank'],left_on=['Team'],right_index=True,how='left').fillna(0)['GA_Rank']) #games_vs_tired = np.array([float(i)*0.4 for i in list(weekly_stack.groupby('team_abv')['away_b2b'].apply(lambda x: x[x != ''].count()))]) games_vs_tired = 0.4*np.array(test_df.merge(right=weekly_stack.groupby('team_abv')['away_b2b'].apply(lambda x: x[x != ''].count()),left_on=['Team'],right_index=True,how='left').fillna(0)['away_b2b']) team_score = test_df['Total']+test_df['Off-Night']*0.5+test_df['B2B']*-0.2+games_vs_tired*0.3+gf_rank*0.1+ga_rank*0.1 test_df['Score'] = team_score cols = test_df.columns.tolist(); L = len(cols) test_df = test_df[cols[4:]+cols[0:4]] #return test_df#[cols[4:]+cols[0:4]] test_df = test_df.sort_values(by=[sort_value,'Score'],ascending = ascend) for i in range(0,len(date_list)): test_df[calendar.day_name[date_list[i].weekday()]+'
'+str(date_list[i].month)+'-'+'{:02d}'.format(date_list[i].day)] = test_list[i]['new_text'] row = ['']*L for x in test_df[test_df.columns[L:]]: row.append(int(sum(test_df[x]!=" ")/2)) test_df = test_df.sort_values(by=input.sort_id(),ascending=input.a_d_id()) test_df.loc[32] = row #test_df_html = HTML( test_df.to_html().replace("\\n","
") ) offnight_list = [True if x <8 else False for x in test_df.iloc[-1][L:]] test_df.style.applymap(highlight_cols,subset = ((list(test_df.index[:-1]),test_df.columns[L:][offnight_list]))) test_df_style = test_df.style.set_properties(**{'border': '3 px'},overwrite=False).set_table_styles([{ 'selector': 'caption', 'props': [ ('color', ''), ('fontname', 'Century Gothic'), ('font-size', '20px'), ('font-style', 'italic'), ('font-weight', ''), ('text-align', 'centre'), ] },{'selector' :'th', 'props':[('text-align', 'center'),('Height','px'),('color','black'),('border', '1px black solid !important')]},{'selector' :'td', 'props':[('text-align', 'center'),('font-size', '18px'),('color','black')]}],overwrite=False).set_properties( **{'background-color':'White','index':'White','min-width':'75px'},overwrite=False).set_properties( **{'background-color':'White','index':'White','min-width':'100px'},overwrite=False,subset = ((list(test_df.index[:]),test_df.columns[5:]))).set_table_styles( [{'selector': 'th:first-child', 'props': [('background-color', 'white')]}],overwrite=False).set_table_styles( [{'selector': 'tr:first-child', 'props': [('background-color', 'white')]}],overwrite=False).set_table_styles( [{'selector': 'tr', 'props': [('line-height', '20px')]}],overwrite=False).set_properties( **{'Height': '8px'},**{'text-align': 'center'},overwrite=False).hide_index() test_df_style = test_df_style.applymap(highlight_cols,subset = ((list(test_df.index[:-1]),test_df.columns[L:][offnight_list]))) test_df_style = test_df_style.applymap(highlight_cells) test_df_style = test_df_style.background_gradient(cmap=cmap_total,subset = ((list(test_df.index[:-1]),test_df.columns[0]))) test_df_style = test_df_style.background_gradient(cmap=cmap_total,vmin=0,vmax=np.max(test_df.Total[:len(test_df)-1]),subset = ((list(test_df.index[:-1]),test_df.columns[2]))) test_df_style = test_df_style.background_gradient(cmap=cmap_off,subset = ((list(test_df.index[:-1]),test_df.columns[3]))) test_df_style = test_df_style.background_gradient(cmap=cmap_back,subset = ((list(test_df.index[:-1]),test_df.columns[4]))) test_df_style = test_df_style.background_gradient(cmap=cmap_sum,subset = ((list(test_df.index[-1:]),test_df.columns[L:])),axis=1) test_df_style = test_df_style.set_properties( **{'border': '1px black solid !important'},subset = ((list(test_df.index[:-1]),test_df.columns[:]))).set_properties( **{'min-width':'85px'},subset = ((list(test_df.index[:-1]),test_df.columns[L:])),overwrite=False).set_properties(**{ 'color': 'black'},overwrite=False).set_properties( **{'border': '1px black solid !important'},subset = ((list(test_df.index[:]),test_df.columns[L:]))) test_df_style = test_df_style.format( '{:.0f}',subset=(test_df.index[:-1],test_df.columns[2:L])) test_df_style = test_df_style.format( '{:.1f}',subset=(test_df.index[:-1],test_df.columns[0])) print('made it to teh end') return test_df_style #return exit_velo_df_codes_summ_time_style_set # @output # @render.plot(alt="A histogram") # def plot_pitch(): # p @output @render.table def schedule_result_legend(): off_b2b_df = pd.DataFrame(data={'off':'Off-Night','b2b':'Tired Opp. 😴'},index=[0]) #off_b2b_df.style.applymap(highlight_cols,subset = ((list(off_b2b_df.index[:-1]),off_b2b_df.columns[0]))) off_b2b_df_style = off_b2b_df.style.set_properties(**{'border': '3 px'},overwrite=False).set_table_styles([{ 'selector': 'caption', 'props': [ ('color', ''), ('fontname', 'Century Gothic'), ('font-size', '20px'), ('font-style', 'italic'), ('font-weight', ''), ('text-align', 'centre'), ] },{'selector' :'th', 'props':[('text-align', 'center'),('Height','px'),('color','black'),( 'border', '1px black solid !important')]},{'selector' :'td', 'props':[('text-align', 'center'),('font-size', '18px'),('color','black')]}],overwrite=False).set_properties( **{'background-color':'White','index':'White','min-width':'150px'},overwrite=False).set_table_styles( [{'selector': 'th:first-child', 'props': [('background-color', 'white')]}],overwrite=False).set_table_styles( [{'selector': 'tr:first-child', 'props': [('background-color', 'white')]}],overwrite=False).set_table_styles( [{'selector': 'tr', 'props': [('line-height', '20px')]}],overwrite=False).set_properties( **{'Height': '8px'},**{'text-align': 'center'},overwrite=False).set_properties( **{'background-color':'#C2FEE9'},subset=off_b2b_df.columns[0]).set_properties( **{'color':'black'},subset=off_b2b_df.columns[:]).hide_index().set_table_styles([ {'selector': 'thead', 'props': [('display', 'none')]} ]).set_properties(**{'border': '3 px','color':'black'},overwrite=False).set_properties( **{'border': '1px black solid !important'},subset = ((list(off_b2b_df.index[:]),off_b2b_df.columns[:]))).set_properties( **{'min-width':'130'},subset = ((list(off_b2b_df.index[:]),off_b2b_df.columns[:])),overwrite=False).set_properties(**{ 'color': 'black'},overwrite=False).set_properties( **{'border': '1px black solid !important'},subset = ((list(off_b2b_df.index[:]),off_b2b_df.columns[:]))) return off_b2b_df_style app = App(app_ui, server)