diff --git "a/app_all.py" "b/app_all.py"
deleted file mode 100644--- "a/app_all.py"
+++ /dev/null
@@ -1,3474 +0,0 @@
-import pandas as pd
-import numpy as np
-import requests
-import math
-import matplotlib.pyplot as plt
-import seaborn as sns
-import matplotlib.patches as patches
-import matplotlib.colors as mcolors
-import matplotlib
-import inflect
-infl = inflect.engine()
-from matplotlib.offsetbox import (OffsetImage, AnnotationBbox)
-from matplotlib.colors import Normalize
-from matplotlib.ticker import FuncFormatter
-import matplotlib.ticker as mtick
-from matplotlib.colors import Normalize
-import urllib
-import urllib.request
-import urllib.error
-from urllib.error import HTTPError
-import time
-from shinywidgets import output_widget, render_widget
-import shinyswatch
-from shiny import App, Inputs, Outputs, Session, reactive, render, req, ui
-
-column_list = ['woba_percent',
- 'woba_percent_contact',
- 'barrel_percent',
- 'sweet_spot_percent',
- 'hard_hit_percent',
- 'launch_speed',
- 'launch_speed_90',
- 'max_launch_speed',
- 'k_percent',
- 'bb_percent',
- 'swing_percent',
- 'whiff_rate',
- 'zone_swing_percent',
- 'zone_contact_percent',
- 'chase_percent',
- 'chase_contact']
-column_list_pitch = ['pitches','bip','woba_percent_contact','whiff_rate','chase_percent']
-
-import joblib
-
-
-loaded_model = joblib.load('C:/Users/thoma/Google Drive/Python/Baseball/season_stats/2024/joblib_model/barrel_model.joblib')
-in_zone_model = joblib.load('C:/Users/thoma/Google Drive/Python/Baseball/season_stats/2024/joblib_model/in_zone_model_knn_20240410.joblib')
-
-stat_plot_dict = {'woba_percent':{'name':'wOBA','format':'.3f','flip':False},
- 'woba_percent_contact':{'name':'wOBACON','format':'.3f','flip':False},
- 'barrel_percent':{'name':'Barrel%','format':'.1%','flip':False},
- 'max_launch_speed':{'name':'Max EV','format':'.1f','flip':False},
- 'launch_speed_90':{'name':'90th% EV','format':'.1f','flip':False},
- 'launch_speed':{'name':'Avg EV','format':'.1f','flip':False},
- 'sweet_spot_percent':{'name':'SwSpot%','format':'.1%','flip':False},
- 'hard_hit_percent':{'name':'HardHit%','format':'.1%','flip':False},
- 'k_percent':{'name':'K%','format':'.1%','flip':True},
- 'bb_percent':{'name':'BB%','format':'.1%','flip':False},
- 'zone_contact_percent':{'name':'Z-Contact%','format':'.1%','flip':False},
- 'zone_swing_percent':{'name':'Z-Swing%','format':'.1%','flip':False},
- 'zone_percent':{'name':'Zone%','format':'.1%','flip':False},
- 'chase_percent':{'name':'O-Swing%','format':'.1%','flip':True},
- 'chase_contact':{'name':'O-Contact%','format':'.1%','flip':False},
- 'swing_percent':{'name':'Swing%','format':'.1%','flip':False},
- 'whiff_rate':{'name':'Whiff%','format':'.1%','flip':True},
- 'bip':{'name':'Balls in Play','format':'.0f','flip':False},
- 'pitches':{'name':'Pitches','format':'.0f','flip':False},}
-
-stat_plot_dict_rolling = {'woba_percent':{'name':'wOBA','format':'.3f','flip':False,'y':'woba','div':'woba_codes','y_min':0.2,'y_max':0.6,'x_label':'wOBA PA','form':'3f'},
- 'k_percent':{'name':'K%','format':'.1%','flip':True,'y':'k','div':'pa','y_min':0.0,'y_max':0.4,'x_label':'PA','form':'1%'},
- 'bb_percent':{'name':'BB%','format':'.1%','flip':False,'y':'bb','div':'pa','y_min':0.0,'y_max':0.3,'x_label':'PA','form':'1%'},
- 'zone_contact_percent':{'name':'Z-Contact%','format':'.1%','flip':False,'y':'zone_contact','div':'zone_swing','y_min':0.6,'y_max':1.0,'x_label':'In-Zone Swings','form':'1%'},
- 'zone_swing_percent':{'name':'Z-Swing%','format':'.1%','flip':False,'y':'zone_swing','div':'in_zone','y_min':0.5,'y_max':1.0,'x_label':'In-Zone Pitches','form':'1%'},
- 'zone_percent':{'name':'Zone%','format':'.1%','flip':False,'y':'in_zone','div':'pitches','y_min':0.3,'y_max':0.7,'x_label':'Pitches','form':'1%'},
- 'chase_percent':{'name':'O-Swing%','format':'.1%','flip':True,'y':'ozone_swing','div':'out_zone','y_min':0.1,'y_max':0.4,'x_label':'Out-of-Zone Pitches','form':'1%'},
- 'chase_contact':{'name':'O-Contact%','format':'.1%','flip':False,'y':'ozone_contact','div':'ozone_swing','y_min':0.4,'y_max':0.8,'x_label':'Out-of-Zone Swings','form':'1%'},
- 'swing_percent':{'name':'Swing%','format':'.1%','flip':False,'y':'swings','div':'pitches','y_min':0.3,'y_max':0.7,'x_label':'Pitches','form':'1%'},
- 'whiff_rate':{'name':'Whiff%','format':'.1%','flip':True,'y':'whiffs','div':'swings','y_min':0.0,'y_max':0.5,'x_label':'Swings','form':'1%'},}
-
-cmap_sum = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#0C7BDC","#FFFFFF","#FFB000"])
-cmap_sum_r = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#FFB000","#FFFFFF","#0C7BDC",])
-cmap_sum.set_bad(color='#C7C7C7', alpha=1.0)
-cmap_sum_r.set_bad(color='#C7C7C7', alpha=1.0)
-
-from batting_update import df_update,df_update_summ_avg,df_update_summ,df_summ_batter_pitch_up,df_summ_changes,df_summ_filter_out
-
-def percentile(n):
- def percentile_(x):
- return np.nanpercentile(x, n)
- percentile_.__name__ = 'percentile_%s' % n
- return percentile_
-
-print('Reading A')
-
-df_a = pd.read_csv("C:/Users/thoma/Google Drive/Python/Baseball/season_stats/2024/milb/lo_a/2024_regular_data.csv",index_col=[0])
-print('Reading A+')
-df_ha = pd.read_csv("C:/Users/thoma/Google Drive/Python/Baseball/season_stats/2024/milb/hi_a/2024_regular_data.csv",index_col=[0])
-print('Reading AA')
-df_aa = pd.read_csv("C:/Users/thoma/Google Drive/Python/Baseball/season_stats/2024/milb/aa/2024_regular_data.csv",index_col=[0])
-print('Reading AAA')
-df_aaa = pd.read_csv("C:/Users/thoma/Google Drive/Python/Baseball/season_stats/2024/milb/aaa/2024_regular_data.csv",index_col=[0])
-print('Reading MLB')
-df_mlb = pd.read_csv("C:/Users/thoma/Google Drive/Python/Baseball/season_stats/2024/2024_regular_data.csv",index_col=[0])
-print('Reading LIDOM')
-#df_dom = pd.read_csv('dom_win_league.csv',index_col=[0])
-# df_dom_update = pd.read_csv('dom_win_league_update.csv',index_col=[0])
-
-print('Reading A')
-df_a_update = df_update(df_a)
-print('Reading A+')
-df_ha_update = df_update(df_ha)
-print('Reading AA')
-df_aa_update = df_update(df_aa)
-print('Reading AAA')
-df_aaa_update = df_update(df_aaa)
-print('Reading MLB')
-df_mlb_update = df_update(df_mlb)
-
-
-df_a_update['batter_name'] = df_a_update['batter_name'].str.strip(' ')
-df_ha_update['batter_name'] = df_ha_update['batter_name'].str.strip(' ')
-df_aa_update['batter_name'] = df_aa_update['batter_name'].str.strip(' ')
-df_aaa_update['batter_name'] = df_aaa_update['batter_name'].str.strip(' ')
-df_mlb_update['batter_name'] = df_mlb_update['batter_name'].str.strip(' ')
-# df_dom_update['batter_name'] = df_dom_update['batter_name'].str.strip(' ')
-
-df_a_update['bip'] = df_a_update['bip'].replace({'0':False,'False':False,'True':True})
-df_ha_update['bip'] = df_ha_update['bip'].replace({'0':False,'False':False,'True':True})
-df_aa_update['bip'] = df_aa_update['bip'].replace({'0':False,'False':False,'True':True})
-df_aaa_update['bip'] = df_aaa_update['bip'].replace({'0':False,'False':False,'True':True})
-df_mlb_update['bip'] = df_mlb_update['bip'].replace({'0':False,'False':False,'True':True})
-# df_dom_update['bip'] = df_dom_update['in_play']
-# df_dom_update['bip'] = df_dom_update['bip'].replace({'0':False,'False':False,'True':True})
-
-
-# conditions_woba = [
-# (df_dom_update['event_type']=='walk'),
-# (df_dom_update['event_type']=='hit_by_pitch'),
-# (df_dom_update['event_type']=='single'),
-# (df_dom_update['event_type']=='double'),
-# (df_dom_update['event_type']=='triple'),
-# (df_dom_update['event_type']=='home_run'),
-# ]
-
-choices_woba = [0.696,
- 0.726,
- 0.883,
- 1.244,
- 1.569,
- 2.004]
-
-# df_dom_update['woba'] = np.select(conditions_woba, choices_woba, default=np.nan)
-
-
-woba_codes = ['strikeout', 'field_out', 'single', 'walk', 'hit_by_pitch',
- 'double', 'sac_fly', 'force_out', 'home_run',
- 'grounded_into_double_play', 'fielders_choice', 'field_error',
- 'triple', 'sac_bunt', 'double_play',
- 'fielders_choice_out', 'strikeout_double_play',
- 'sac_fly_double_play', 'other_out']
-
-
-
-#
-
-
-# conditions_woba_code = [
-# (df_dom_update['event_type'].isin(woba_codes))
-# ]
-
-# choices_woba_code = [1]
-
-# df_dom_update['woba_codes'] = np.select(conditions_woba_code, choices_woba_code, default=np.nan)
-
-
-# df_dom_update['woba_contact'] = [df_dom_update['woba'].values[x] if df_dom_update['bip'].values[x] == 1 else np.nan for x in range(len(df_dom_update['woba_codes']))]
-
-
-
-df_a_update['bip_div'] = ~df_a_update.launch_speed.isna()
-df_ha_update['bip_div'] = ~df_ha_update.launch_speed.isna()
-df_aa_update['bip_div'] = ~df_aa_update.launch_speed.isna()
-df_aaa_update['bip_div'] = ~df_aaa_update.launch_speed.isna()
-df_mlb_update['bip_div'] = ~df_mlb_update.launch_speed.isna()
-# df_dom_update['bip_div'] = ~df_dom_update.launch_speed.isna()
-df_a_update['average'] = 'average'
-df_ha_update['average'] = 'average'
-df_aa_update['average'] = 'average'
-df_aaa_update['average'] = 'average'
-df_mlb_update['average'] = 'average'
-#df_dom_update['average'] = 'average'
-
-#df_u['is_pitch']
-
-df_summ_a_update = df_summ_changes(df_update_summ(df_a_update)).set_index(['batter_id','batter_name'])
-df_summ_ha_update = df_summ_changes(df_update_summ(df_ha_update)).set_index(['batter_id','batter_name'])
-df_summ_aa_update = df_summ_changes(df_update_summ(df_aa_update)).set_index(['batter_id','batter_name'])
-df_summ_aaa_update = df_summ_changes(df_update_summ(df_aaa_update)).set_index(['batter_id','batter_name'])
-df_summ_mlb_update = df_summ_changes(df_update_summ(df_mlb_update)).set_index(['batter_id','batter_name'])
-# df_summ_dom_update = df_summ_changes(df_update_summ(df_dom_update)).set_index(['batter_id','batter_name'])
-
-df_summ_avg_a_update = df_summ_changes(df_update_summ_avg(df_a_update)).set_index(['average'])
-df_summ_avg_ha_update = df_summ_changes(df_update_summ_avg(df_ha_update)).set_index(['average'])
-df_summ_avg_aa_update = df_summ_changes(df_update_summ_avg(df_aa_update)).set_index(['average'])
-df_summ_avg_aaa_update = df_summ_changes(df_update_summ_avg(df_aaa_update)).set_index(['average'])
-df_summ_avg_mlb_update = df_summ_changes(df_update_summ_avg(df_mlb_update)).set_index(['average'])
-# df_summ_avg_dom_update = df_summ_changes(df_update_summ_avg(df_dom_update)).set_index(['average'])
-
-stat_roll_dict = dict(zip(stat_plot_dict_rolling.keys(),
- [stat_plot_dict_rolling[x]['name'] for x in stat_plot_dict_rolling]))
-
-mlb_player_dict = df_mlb_update.drop_duplicates(
- 'batter_id')[['batter_id','batter_name']].sort_values(by='batter_name').set_index('batter_id').to_dict()['batter_name']
-aaa_player_dict = df_aaa_update.drop_duplicates(
- 'batter_id')[['batter_id','batter_name']].sort_values(by='batter_name').set_index('batter_id').to_dict()['batter_name']
-aa_player_dict = df_aa_update.drop_duplicates(
- 'batter_id')[['batter_id','batter_name']].sort_values(by='batter_name').set_index('batter_id').to_dict()['batter_name']
-ha_player_dict = df_ha_update.drop_duplicates(
- 'batter_id')[['batter_id','batter_name']].sort_values(by='batter_name').set_index('batter_id').to_dict()['batter_name']
-a_player_dict = df_a_update.drop_duplicates(
- 'batter_id')[['batter_id','batter_name']].sort_values(by='batter_name').set_index('batter_id').to_dict()['batter_name']
-# dom_player_dict = df_summ_dom_update.reset_index().drop_duplicates(
-# 'batter_id')[['batter_id','batter_name']].sort_values(by='batter_name').set_index('batter_id').to_dict()['batter_name']
-
-
-
-
-def server(input: Inputs, output: Outputs, session: Session):
- @render.ui
- def test():
- # @reactive.Effect
- if input.my_tabs() == 'MLB':
- print(mlb_player_dict)
- return ui.input_select("player_id", "Select Batter",mlb_player_dict,selectize=True)
- if input.my_tabs() == 'AAA':
- return ui.input_select("player_id", "Select Batter",aaa_player_dict,selectize=True)
- if input.my_tabs() == 'AA':
- return ui.input_select("player_id", "Select Batter",aa_player_dict,selectize=True)
- if input.my_tabs() == 'High-A':
- return ui.input_select("player_id", "Select Batter",ha_player_dict,selectize=True)
- if input.my_tabs() == 'A':
- return ui.input_select("player_id", "Select Batter",a_player_dict,selectize=True)
- # if input.my_tabs() == 'LIDOM':
- # return ui.input_select("player_id", "Select Batter",dom_player_dict,selectize=True)
-
-
-
- @output
- @render.plot(alt="MLB Plot")
- @reactive.event(input.go, ignore_none=False)
- def mlb_plot():
- ### Iniput data for the level
- #time.sleep(2)
- df_update = df_mlb_update.copy()
- df_summ_update = df_summ_mlb_update.copy()
- df_summ_avg_update = df_summ_avg_mlb_update.copy()
-
- if len(input.player_id()) < 1:
- fig, ax = plt.subplots(1,1,figsize=(10,10))
- ax.text(s='Please Select a Batter',x=0.5,y=0.5, ha='center')
- ax.axis('off')
- return fig
-
-
- batter_select = int(input.player_id())
- sport_id_input = 1
- df_roll = df_update[df_update['batter_id']==batter_select]
- if len(df_roll) == 0:
- fig, ax = plt.subplots(1,1,figsize=(10,10))
- ax.text(s='Card is Generating',x=0.5,y=0.5, ha='center')
- ax.axis('off')
- return fig
-
-
- df_summ_filter = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[0]
- df_summ_filter_pct = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[1]
- df_summ_player = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[2]
- df_summ_player_pct = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[3]
-
- df_summ_batter_pitch = df_summ_batter_pitch_up(df= df_update).set_index(['batter_id','batter_name','pitch_category'])
-
-
- df_summ_batter_pitch_pct = df_summ_batter_pitch.loc[df_summ_filter.index.get_level_values(0)]
- df_summ_batter_pitch_pct = df_summ_batter_pitch_pct[df_summ_batter_pitch_pct['pitches']>0]
- df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct.groupby(level='pitch_category').apply(lambda x: x.rank(pct=True)).xs(batter_select,level=0)
-
-
- df_summ_batter_pitch_pct_rank['pitch_count'] = df_summ_batter_pitch_pct_rank.index.get_level_values(1).map(df_summ_batter_pitch.xs(batter_select,level=0).reset_index().set_index('pitch_category')['pitches'].to_dict())
- df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct_rank.sort_values('pitch_count',ascending=False)
- def get_color(value, vmin, vmax, cmap_name=cmap_sum):
- # Normalize the value within the range [0, 1]
- normalized_value = (value - vmin) / (vmax - vmin)
-
- # Get the colormap
- cmap = plt.get_cmap(cmap_name)
-
- # Map the normalized value to a color in the colormap
- color = cmap(normalized_value)
-
- # Convert the color from RGBA to hexadecimal format
- hex_color = mcolors.rgb2hex(color)
-
- return hex_color
-
- def get_players(sport_id=1):
- player_data = requests.get(url=f'https://statsapi.mlb.com/api/v1/sports/{sport_id}/players').json()
-
- #Select relevant data that will help distinguish players from one another
- fullName_list = [x['fullName'] for x in player_data['people']]
- id_list = [x['id'] for x in player_data['people']]
- position_list = [x['primaryPosition']['abbreviation'] for x in player_data['people']]
- team_list = [x['currentTeam']['id']for x in player_data['people']]
- age_list = [x['currentAge']for x in player_data['people']]
-
- player_df = pd.DataFrame(data={'player_id':id_list,
- 'name':fullName_list,
- 'position':position_list,
- 'team':team_list,
- 'age':age_list})
- return player_df
-
- def get_teams():
- teams = requests.get(url='https://statsapi.mlb.com/api/v1/teams/').json()
- #Select only teams that are at the MLB level
- # mlb_teams_city = [x['franchiseName'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_name = [x['teamName'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_franchise = [x['name'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_id = [x['id'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_abb = [x['abbreviation'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
-
- mlb_teams_city = [x['franchiseName'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_name = [x['teamName'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_franchise = [x['name'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_id = [x['id'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_abb = [x['abbreviation'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_parent_id = [x['parentOrgId'] if 'parentOrgId' in x else None for x in teams['teams']]
- mlb_teams_parent = [x['parentOrgName'] if 'parentOrgName' in x else None for x in teams['teams']]
- mlb_teams_league_id = [x['league']['id'] if 'id' in x['league'] else None for x in teams['teams']]
- mlb_teams_league_name = [x['league']['name'] if 'name' in x['league'] else None for x in teams['teams']]
-
-
-
- #Create a dataframe of all the teams
- mlb_teams_df = pd.DataFrame(data={'team_id':mlb_teams_id,
- 'city':mlb_teams_franchise,
- 'name':mlb_teams_name,
- 'franchise':mlb_teams_franchise,
- 'abbreviation':mlb_teams_abb,
- 'parent_org_id':mlb_teams_parent_id,
- 'parent_org':mlb_teams_parent,
- 'league_id':mlb_teams_league_id,
- 'league_name':mlb_teams_league_name
-
- }).drop_duplicates().dropna(subset=['team_id']).reset_index(drop=True).sort_values('team_id')
-
- mlb_teams_df.loc[mlb_teams_df['parent_org_id'].isnull(),'parent_org_id'] = mlb_teams_df.loc[mlb_teams_df['parent_org_id'].isnull(),'team_id']
- mlb_teams_df.loc[mlb_teams_df['parent_org'].isnull(),'parent_org'] = mlb_teams_df.loc[mlb_teams_df['parent_org'].isnull(),'franchise']
-
-
- mlb_teams_df['parent_org_abbreviation'] = mlb_teams_df['parent_org_id'].map(mlb_teams_df.set_index('team_id')['abbreviation'].to_dict())
-
- mlb_teams_df = pd.concat([mlb_teams_df, pd.DataFrame({'team_id': 11,
- 'city': 'Major League Baseball',
- 'name': 'Major League Baseball',
- 'franchise': 'Free Agent',
- 'abbreviation': 'MLB',
- 'parent_org_id': 11,
- 'parent_org': 'Major League Baseball',
- 'league_id': 1.0,
- 'league_name': 'Major League Baseball',
- 'parent_org_abbreviation': 'MLB'},index=[0])]).reset_index(drop=True)
-
- #mlb_teams_df.loc[mlb_teams_df.franchise.isin(mlb_teams_df.parent_org.unique()),'parent_org'] = mlb_teams_df.loc[mlb_teams_df.franchise.isin(mlb_teams_df.parent_org.unique()),'franchise']
-
- return mlb_teams_df
-
- def rolling_plot(stat='k_percent',window_width=100,ax=0,df_r=df_roll,df_r_summ_avg=pd.DataFrame(),stat_plot_dict_rolling=stat_plot_dict_rolling):
- plot = sns.lineplot(x=range(window_width,len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]>0])+1),
- y=df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1].fillna(0).rolling(window=window_width)[stat_plot_dict_rolling[stat]['y']].sum().dropna()/window_width,
- ax=ax,
- color="#FFB000",
- zorder=10)
-
-
-
- # ["#0C7BDC","#FFFFFF","#FFB000"])
- ax.set_xlim(window_width,len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]))
- ax.set_xlabel(stat_plot_dict_rolling[stat]['x_label'],fontsize=8)
- ax.set_ylabel(stat_plot_dict_rolling[stat]['name'],fontsize=8)
-
- ax.hlines(df_r_summ_avg[stat_plot_dict_rolling[stat]['y']]/df_r_summ_avg[stat_plot_dict_rolling[stat]['div']],
- xmin=window_width,
- xmax=len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]),
- color="#0C7BDC",linestyles='-.')
- ax.hlines(sum(df_r[stat_plot_dict_rolling[stat]['y']].dropna())/sum(df_r[stat_plot_dict_rolling[stat]['div']].dropna()),
- xmin=window_width,
- xmax=len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]),
- color="#FFB000",linestyles='--')
- #print(sum(df_r[stat_plot_dict_rolling[stat]['y']].dropna())/sum(df_r[stat_plot_dict_rolling[stat]['div']].dropna()))
- ax.tick_params(axis='x', labelsize=8) # Set x-axis ticks size
- ax.tick_params(axis='y', labelsize=8) # Set y-axis ticks size
- ax.set_title(f"{window_width} {stat_plot_dict_rolling[stat]['x_label']} Rolling {stat_plot_dict_rolling[stat]['name']}",fontsize=8)
- ax.set_ylim(stat_plot_dict_rolling[stat]['y_min'],stat_plot_dict_rolling[stat]['y_max'])
- ax.grid(True,alpha=0.2)
-
-
- if stat_plot_dict_rolling[stat]['form'] == '3f':
- ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('{x:.3f}'))
-
- elif stat_plot_dict_rolling[stat]['form'] == '1f':
- ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('{x:.1f}'))
-
- elif stat_plot_dict_rolling[stat]['form'] == '1%':
- ax.yaxis.set_major_formatter(mtick.PercentFormatter(1))
-
- return plot
-
- dict_level = {1:'MLB',
- 11:'MiLB AAA',
- 12:'MiLB AA',
- 13:'MiLB High-A',
- 14:'MiLB A'}
-
- def plot_card(sport_id_input=sport_id_input,
- batter_select=batter_select,
- df_roll=df_roll,
- df_summ_player=df_summ_player,
- df_summ_update = df_summ_update,
- df_summ_batter_pitch_pct=df_summ_batter_pitch_pct,
- ):
-
- #player_df = get_players(sport_id=sport_id_input)
- mlb_teams = get_teams()
- team_logos = pd.read_csv('team_logos.csv')
- if sport_id_input == 1:
- player_bio = requests.get(f'https://statsapi.mlb.com/api/v1/people?personIds={batter_select}&appContext=majorLeague&hydrate=currentTeam').json()
- else:
- player_bio = requests.get(f'https://statsapi.mlb.com/api/v1/people?personIds={batter_select}&appContext=minorLeague&hydrate=currentTeam').json()
-
- fig = plt.figure(figsize=(10, 10))#,dpi=600)
- plt.rcParams.update({'figure.autolayout': True})
- fig.set_facecolor('white')
- sns.set_theme(style="whitegrid", palette="pastel")
- from matplotlib.gridspec import GridSpec
- gs = GridSpec(5, 5, width_ratios=[0.2,1,1,1,0.2], height_ratios=[0.6,0.05,0.15,.30,0.025])
- #gs.update(hspace=0, wspace=0)
-
- # gs.update(left=0.1,right=0.9,top=0.97,bottom=0.03,wspace=0.3,hspace=0.09)
-
- # ax1 = plt.subplot(4,1,1)
- # ax2 = plt.subplot(2,2,2)
- # ax3 = plt.subplot(2,2,3)
- # ax4 = plt.subplot(4,1,4)
- #ax2 = plt.subplot(3,3,2)
-
- # Add subplots to the grid
- ax = fig.add_subplot(gs[0, :])
- #ax1 = fig.add_subplot(gs[2, 0])
- # ax2 = fig.add_subplot(gs[2, :]) # Subplot at the top-right position
- # fig, ax = plt.subplots(1,1,figsize=(10,12))
- ax.axis('off')
-
- width = 0.08
- height = width*2.45
- if df_summ_player['launch_speed'].isna().values[0]:
- df_summ_player['sweet_spot_percent'] = np.nan
- df_summ_player['barrel_percent'] = np.nan
- df_summ_player['hard_hit_percent'] = np.nan
- if df_summ_player['launch_speed'].isna().values[0]:
- df_summ_player_pct['sweet_spot_percent'] = np.nan
- df_summ_player_pct['barrel_percent'] = np.nan
- df_summ_player_pct['hard_hit_percent'] = np.nan
- # x = 0.1
- # y = 0.9
- for cat in range(len(column_list)):
-
- # if cat < len(column_list)/2:
- x_adjust, y_adjust =(0.85/7*8)*cat/8+0.075 - (0.85/7*8)*math.floor((cat)/8), 0.45-math.floor((cat)/8)/3.2
-
- # else:
- # x_adjust, y_adjust = (cat-len(column_list)/2)*(1.7/(math.ceil((len(column_list)-1))))+0.1, 0.5
- #print( x_adjust, y_adjust)
- if sum(df_summ_player[column_list[cat]].isna()) < 1:
- print(f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}')
- ax.text(s = f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}'.format().strip(),
-
- x = x_adjust,
- y = y_adjust,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 16,
- ha='center',
- va='center')
-
- if stat_plot_dict[column_list[cat]]['flip']:
-
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum_r))
- ax.add_patch(bbox)
-
-
- else:
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum))
- ax.add_patch(bbox)
- else:
- print(f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}')
- ax.text(s = f'{df_summ_player[column_list[cat]].fillna("N/A").values[0]}',
-
- x = x_adjust,
- y = y_adjust,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- if stat_plot_dict[column_list[cat]]['flip']:
-
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum_r))
- ax.add_patch(bbox)
-
-
- else:
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum))
- ax.add_patch(bbox)
-
- ax.text(s = stat_plot_dict[column_list[cat]]['name'],
-
- x = x_adjust,
- y = y_adjust-0.14,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 12,
- ha='center',
- va='center')
-
- ax.text(s = f"{player_bio['people'][0]['fullName']}",
-
- x = 0.5,
- y = 0.95,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 28,
- ha='center',
- va='center')
- if 'parentOrgId' in player_bio['people'][0]['currentTeam']:
-
- ax.text(s = f"{player_bio['people'][0]['primaryPosition']['abbreviation']}, {mlb_teams[mlb_teams['team_id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['franchise'].values[0]}",
-
- x = 0.5,
- y = 0.85,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- else: ax.text(s = f"{player_bio['people'][0]['primaryPosition']['abbreviation']}, {player_bio['people'][0]['currentTeam']['name']}",
-
- x = 0.5,
- y = 0.85,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- ax.text(s =
- f"B/T: {player_bio['people'][0]['batSide']['code']}/"
- f"{player_bio['people'][0]['pitchHand']['code']} "
- f"{player_bio['people'][0]['height']}/"
- f"{player_bio['people'][0]['weight']}",
-
- x = 0.5,
- y = 0.785,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- ax.text(s =
-
- f"DOB: {player_bio['people'][0]['birthDate']} "
- f"Age: {player_bio['people'][0]['currentAge']}",
- x = 0.5,
- y = 0.72,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
- if sport_id_input == 1:
- try:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/{batter_select}/headshot/67/current.png'
- test_mage = plt.imread(url)
- except urllib.error.HTTPError as err:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/1/headshot/67/current.png'
-
- else:
- try:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/c_fill,g_auto/w_180/v1/people/{batter_select}/headshot/milb/current.png'
- test_mage = plt.imread(url)
- except urllib.error.HTTPError as err:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/1/headshot/67/current.png'
- im = plt.imread(url)
- # response = requests.get(url)
- # im = Image.open(BytesIO(response.content), cmap='viridis')
- # im = plt.imread(np.array(PIL.Image.open(urllib.request.urlopen(url))))
-
- # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- imagebox = OffsetImage(im, zoom = 0.35)
- ab = AnnotationBbox(imagebox, (0.125, 0.8), frameon = False)
- ax.add_artist(ab)
-
- if 'parentOrgId' in player_bio['people'][0]['currentTeam']:
- url = team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0]
-
- im = plt.imread(url)
- # response = requests.get(url)
- # im = Image.open(BytesIO(response.content))
- # im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0])
- # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- imagebox = OffsetImage(im, zoom = 0.25)
- ab = AnnotationBbox(imagebox, (0.875, 0.8), frameon = False)
- ax.add_artist(ab)
-
- else:
- url = team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['id']]['imageLink'].values[0]
- im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['id']]['imageLink'].values[0])
-
- # im = plt.imread(url)
- # response = requests.get(url)
- # im = Image.open(BytesIO(response.content))
- #im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0])
-
- # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- imagebox = OffsetImage(im, zoom = 0.25)
- ab = AnnotationBbox(imagebox, (0.875, 0.8), frameon = False)
- ax.add_artist(ab)
-
- ax.text(s = f'2023 {dict_level[sport_id_input]} Metrics',
-
- x = 0.5,
- y = 0.62,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 20,
- ha='center',
- va='center')
-
- df_plot = df_summ_batter_pitch[column_list_pitch].xs([batter_select,df_summ_update.xs(batter_select,level=0).index[0]]).sort_values('pitches',ascending=False)#.dropna()
- df_plot = df_plot[df_plot['pitches'] > 0]
-
- df_plot_pct = df_summ_batter_pitch_pct[column_list_pitch].xs([batter_select,df_summ_update.xs(batter_select,level=0).index[0]]).sort_values('pitches',ascending=False)#.dropna()
-
- value = 1
-
- # df_summ_batter_pitch_pct_rank['pitch_count'] = df_summ_batter_pitch_pct_rank.index.get_level_values(1).map(df_plot['pitches'].to_dict())
- # df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct_rank.sort_values('pitch_count',ascending=False)
- # Normalize the value
- colormap = plt.get_cmap(cmap_sum)
- colormap_r = plt.get_cmap(cmap_sum_r)
- norm = Normalize(vmin=0, vmax=1)
-
- col_5_colour = [colormap_r(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['chase_percent']))]
- col_4_colour = [colormap_r(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['whiff_rate']))]
- col_3_colour = [colormap(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['woba_percent_contact']))]
- col_2_colour = ['white']*len(df_summ_batter_pitch_pct_rank)
- col_1_colour = ['white']*len(df_summ_batter_pitch_pct_rank)
- colour_df = pd.DataFrame(data=[col_1_colour,col_2_colour,col_3_colour,col_4_colour,col_5_colour]).T.values
-
-
-
- # col_5_colour = [colormap_r(norm(x)) for x in list((df_plot['chase_percent']))]
- # col_4_colour = [colormap_r(norm(x)) for x in list((df_plot['whiff_rate']))]
- # col_3_colour = [colormap(norm(x)) for x in list((df_plot['woba_percent_contact']))]
- # col_2_colour = ['white']*len(df_plot)
- # col_1_colour = ['white']*len(df_plot)
- # colour_df = pd.DataFrame(data=[col_1_colour,col_2_colour,col_3_colour,col_4_colour,col_5_colour]).T.values
-
- ax_table = fig.add_subplot(gs[2, 1:-1])
- ax_table.axis('off')
- table = ax_table.table(cellText=df_plot.values, colLabels=[stat_plot_dict[x]['name'] for x in df_plot.columns],rowLabels=df_plot.index, cellLoc='center',
- bbox=[0.12, 0.0, 0.88, 1],colWidths=[0.03]+[0.03]*(len(df_plot.columns)),
- loc='center',cellColours=colour_df)
- ax_table.text(x=0.5,y=1.1,s='Metrics By Pitch Type',ha='center',fontdict={ 'size': 12},fontname='arial')
-
- w, h = table[0,1].get_width(), table[0,1].get_height()
- table.add_cell(0, -1, w,h, text='Pitch Type')
- min_font_size = 12
- # Set table properties
- table.auto_set_font_size(False)
- table.set_fontsize(min_font_size)
- #table.set_fontname('arial')
- table.scale(1, len(df_plot)*0.3)
-
-
- for n_col in range(0,len(df_plot.columns)):
- #print(df_plot.columns[n_col],f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}")
- format_col = df_plot[df_plot.columns[n_col]].astype(str)
- n_c = 0
- for cell in table.get_celld().values():
- # print([cell.get_text().get_text()],format_col.astype(str).values)
- if cell.get_text().get_text() in format_col.astype(str).values:
-
-
- #print(cell.get_text().get_text() in format_col.astype(str).values)
- cell.get_text().set_text(f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}".format(float(cell.get_text().get_text())))
- elif cell.get_text().get_text()[:-2] in format_col.astype(str).values:
- cell.get_text().set_text(f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}".format(float(cell.get_text().get_text())))
- n_c = n_c + 1
-
- stat_1 = input.stat_1()
- window_width_1 = input.window_1()
- stat_2 = input.stat_2()
- window_width_2 = input.window_2()
- stat_3 = input.stat_3()
- window_width_3 = input.window_3()
-
-
- inset_ax = ax = fig.add_subplot(gs[3, 1])
- rolling_plot(stat=stat_1,window_width=window_width_1,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- inset_ax = ax = fig.add_subplot(gs[3, 2])
- rolling_plot(stat=stat_2,window_width=window_width_2,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- inset_ax = ax = fig.add_subplot(gs[3, 3])
- rolling_plot(stat=stat_3,window_width=window_width_3,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- ax_bot = ax = fig.add_subplot(gs[4, :])
-
- ax_bot.text(x=0.05,y=-0.5,s='By: @TJStats',ha='left',fontdict={ 'size': 14},fontname='arial')
- ax_bot.text(x=1-0.05,y=-0.5,s='Data: MLB',ha='right',fontdict={ 'size': 14},fontname='arial')
- ax_bot.axis('off')
-
-
- ax_cbar = fig.add_subplot(gs[1,1:-1])
-
- cb = matplotlib.colorbar.ColorbarBase(ax_cbar, orientation='horizontal',
- cmap=cmap_sum)
- #ax_cbar.axis('off')
- ax_cbar.text(x=0.5,y=1.2,s='Colour Scale - Percentiles',ha='center',fontdict={ 'size': 12},fontname='arial')
- ax_cbar.text(s='0%',x=0.01,y=0.5,va='center',ha='left')
- ax_cbar.text(s='100%',x=0.99,y=0.5,va='center',ha='right')
- # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- ax_cbar.set_xticks([])
- ax_cbar.set_yticks([])
- ax_cbar.set_xticklabels([])
- ax_cbar.set_yticklabels([])
-
- # Display only the outline of the axis
- for spine in ax_cbar.spines.values():
- spine.set_visible(True) # Show only the outline
- spine.set_color('black') # Set the color to black
-
- # fig.set_facecolor('#ffffff')
-
- return fig.tight_layout()
-
-
-
- return plot_card(sport_id_input=sport_id_input,
- batter_select=batter_select,
- df_roll=df_roll,
- df_summ_player=df_summ_player,
- df_summ_batter_pitch_pct=df_summ_batter_pitch_pct,
- )
- @output
- @render.plot(alt="AAA Plot")
- @reactive.event(input.go, ignore_none=False)
- def aaa_plot():
- ### Iniput data for the level
- #time.sleep(2)
- df_update = df_aaa_update.copy()
- df_summ_update = df_summ_aaa_update.copy()
- df_summ_avg_update = df_summ_avg_aaa_update.copy()
-
- if len(input.player_id()) < 1:
- fig, ax = plt.subplots(1,1,figsize=(10,10))
- ax.text(s='Please Select a Batter',x=0.5,y=0.5, ha='center')
- ax.axis('off')
- return fig
-
-
- batter_select = int(input.player_id())
- sport_id_input = 11
- df_roll = df_update[df_update['batter_id']==batter_select]
- if len(df_roll) == 0:
- fig, ax = plt.subplots(1,1,figsize=(10,10))
- ax.text(s='Card is Generating',x=0.5,y=0.5, ha='center')
- ax.axis('off')
- return fig
-
-
- df_summ_filter = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[0]
- df_summ_filter_pct = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[1]
- df_summ_player = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[2]
- df_summ_player_pct = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[3]
-
- df_summ_batter_pitch = df_summ_batter_pitch_up(df= df_update).set_index(['batter_id','batter_name','pitch_category'])
-
-
- df_summ_batter_pitch_pct = df_summ_batter_pitch.loc[df_summ_filter.index.get_level_values(0)]
- df_summ_batter_pitch_pct = df_summ_batter_pitch_pct[df_summ_batter_pitch_pct['pitches']>0]
- df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct.groupby(level='pitch_category').apply(lambda x: x.rank(pct=True)).xs(batter_select,level=0)
-
- df_summ_batter_pitch_pct_rank['pitch_count'] = df_summ_batter_pitch_pct_rank.index.get_level_values(1).map(df_summ_batter_pitch.xs(batter_select,level=0).reset_index().set_index('pitch_category')['pitches'].to_dict())
- df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct_rank.sort_values('pitch_count',ascending=False)
- #df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct_rank.dropna()
- def get_color(value, vmin, vmax, cmap_name=cmap_sum):
- # Normalize the value within the range [0, 1]
- normalized_value = (value - vmin) / (vmax - vmin)
-
- # Get the colormap
- cmap = plt.get_cmap(cmap_name)
-
- # Map the normalized value to a color in the colormap
- color = cmap(normalized_value)
-
- # Convert the color from RGBA to hexadecimal format
- hex_color = mcolors.rgb2hex(color)
-
- return hex_color
-
- def get_players(sport_id=1):
- player_data = requests.get(url=f'https://statsapi.mlb.com/api/v1/sports/{sport_id}/players').json()
-
- #Select relevant data that will help distinguish players from one another
- fullName_list = [x['fullName'] for x in player_data['people']]
- id_list = [x['id'] for x in player_data['people']]
- position_list = [x['primaryPosition']['abbreviation'] for x in player_data['people']]
- team_list = [x['currentTeam']['id']for x in player_data['people']]
- age_list = [x['currentAge']for x in player_data['people']]
-
- player_df = pd.DataFrame(data={'player_id':id_list,
- 'name':fullName_list,
- 'position':position_list,
- 'team':team_list,
- 'age':age_list})
- return player_df
-
- def get_teams():
- teams = requests.get(url='https://statsapi.mlb.com/api/v1/teams/').json()
- #Select only teams that are at the MLB level
- # mlb_teams_city = [x['franchiseName'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_name = [x['teamName'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_franchise = [x['name'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_id = [x['id'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_abb = [x['abbreviation'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
-
- mlb_teams_city = [x['franchiseName'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_name = [x['teamName'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_franchise = [x['name'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_id = [x['id'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_abb = [x['abbreviation'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_parent_id = [x['parentOrgId'] if 'parentOrgId' in x else None for x in teams['teams']]
- mlb_teams_parent = [x['parentOrgName'] if 'parentOrgName' in x else None for x in teams['teams']]
- mlb_teams_league_id = [x['league']['id'] if 'id' in x['league'] else None for x in teams['teams']]
- mlb_teams_league_name = [x['league']['name'] if 'name' in x['league'] else None for x in teams['teams']]
-
-
-
- #Create a dataframe of all the teams
- mlb_teams_df = pd.DataFrame(data={'team_id':mlb_teams_id,
- 'city':mlb_teams_franchise,
- 'name':mlb_teams_name,
- 'franchise':mlb_teams_franchise,
- 'abbreviation':mlb_teams_abb,
- 'parent_org_id':mlb_teams_parent_id,
- 'parent_org':mlb_teams_parent,
- 'league_id':mlb_teams_league_id,
- 'league_name':mlb_teams_league_name
-
- }).drop_duplicates().dropna(subset=['team_id']).reset_index(drop=True).sort_values('team_id')
-
- mlb_teams_df.loc[mlb_teams_df['parent_org_id'].isnull(),'parent_org_id'] = mlb_teams_df.loc[mlb_teams_df['parent_org_id'].isnull(),'team_id']
- mlb_teams_df.loc[mlb_teams_df['parent_org'].isnull(),'parent_org'] = mlb_teams_df.loc[mlb_teams_df['parent_org'].isnull(),'franchise']
-
-
- mlb_teams_df['parent_org_abbreviation'] = mlb_teams_df['parent_org_id'].map(mlb_teams_df.set_index('team_id')['abbreviation'].to_dict())
-
- mlb_teams_df = pd.concat([mlb_teams_df, pd.DataFrame({'team_id': 11,
- 'city': 'Major League Baseball',
- 'name': 'Major League Baseball',
- 'franchise': 'Free Agent',
- 'abbreviation': 'MLB',
- 'parent_org_id': 11,
- 'parent_org': 'Major League Baseball',
- 'league_id': 1.0,
- 'league_name': 'Major League Baseball',
- 'parent_org_abbreviation': 'MLB'},index=[0])]).reset_index(drop=True)
-
- #mlb_teams_df.loc[mlb_teams_df.franchise.isin(mlb_teams_df.parent_org.unique()),'parent_org'] = mlb_teams_df.loc[mlb_teams_df.franchise.isin(mlb_teams_df.parent_org.unique()),'franchise']
-
- return mlb_teams_df
-
- def rolling_plot(stat='k_percent',window_width=100,ax=0,df_r=df_roll,df_r_summ_avg=pd.DataFrame(),stat_plot_dict_rolling=stat_plot_dict_rolling):
- plot = sns.lineplot(x=range(window_width,len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]>0])+1),
- y=df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1].fillna(0).rolling(window=window_width)[stat_plot_dict_rolling[stat]['y']].sum().dropna()/window_width,
- ax=ax,
- color="#FFB000",
- zorder=10)
-
-
-
- # ["#0C7BDC","#FFFFFF","#FFB000"])
- ax.set_xlim(window_width,len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]))
- ax.set_xlabel(stat_plot_dict_rolling[stat]['x_label'],fontsize=8)
- ax.set_ylabel(stat_plot_dict_rolling[stat]['name'],fontsize=8)
-
- ax.hlines(df_r_summ_avg[stat_plot_dict_rolling[stat]['y']]/df_r_summ_avg[stat_plot_dict_rolling[stat]['div']],
- xmin=window_width,
- xmax=len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]),
- color="#0C7BDC",linestyles='-.')
- ax.hlines(sum(df_r[stat_plot_dict_rolling[stat]['y']].dropna())/sum(df_r[stat_plot_dict_rolling[stat]['div']].dropna()),
- xmin=window_width,
- xmax=len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]),
- color="#FFB000",linestyles='--')
- #print(sum(df_r[stat_plot_dict_rolling[stat]['y']].dropna())/sum(df_r[stat_plot_dict_rolling[stat]['div']].dropna()))
- ax.tick_params(axis='x', labelsize=8) # Set x-axis ticks size
- ax.tick_params(axis='y', labelsize=8) # Set y-axis ticks size
- ax.set_title(f"{window_width} {stat_plot_dict_rolling[stat]['x_label']} Rolling {stat_plot_dict_rolling[stat]['name']}",fontsize=8)
- ax.set_ylim(stat_plot_dict_rolling[stat]['y_min'],stat_plot_dict_rolling[stat]['y_max'])
- ax.grid(True,alpha=0.2)
-
-
- if stat_plot_dict_rolling[stat]['form'] == '3f':
- ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('{x:.3f}'))
-
- elif stat_plot_dict_rolling[stat]['form'] == '1f':
- ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('{x:.1f}'))
-
- elif stat_plot_dict_rolling[stat]['form'] == '1%':
- ax.yaxis.set_major_formatter(mtick.PercentFormatter(1))
-
- return plot
-
- dict_level = {1:'MLB',
- 11:'MiLB AAA',
- 12:'MiLB AA',
- 13:'MiLB High-A',
- 14:'MiLB A'}
-
- def plot_card(sport_id_input=sport_id_input,
- batter_select=batter_select,
- df_roll=df_roll,
- df_summ_player=df_summ_player,
- df_summ_update = df_summ_update,
- df_summ_batter_pitch_pct=df_summ_batter_pitch_pct,
- ):
-
- #player_df = get_players(sport_id=sport_id_input)
- mlb_teams = get_teams()
- team_logos = pd.read_csv('team_logos.csv')
- if sport_id_input == 1:
- player_bio = requests.get(f'https://statsapi.mlb.com/api/v1/people?personIds={batter_select}&appContext=majorLeague&hydrate=currentTeam').json()
- else:
- player_bio = requests.get(f'https://statsapi.mlb.com/api/v1/people?personIds={batter_select}&appContext=minorLeague&hydrate=currentTeam').json()
-
- fig = plt.figure(figsize=(10, 10))#,dpi=600)
- plt.rcParams.update({'figure.autolayout': True})
- fig.set_facecolor('white')
- sns.set_theme(style="whitegrid", palette="pastel")
- from matplotlib.gridspec import GridSpec
- gs = GridSpec(5, 5, width_ratios=[0.2,1,1,1,0.2], height_ratios=[0.6,0.05,0.15,.30,0.025])
- #gs.update(hspace=0, wspace=0)
-
- # gs.update(left=0.1,right=0.9,top=0.97,bottom=0.03,wspace=0.3,hspace=0.09)
-
- # ax1 = plt.subplot(4,1,1)
- # ax2 = plt.subplot(2,2,2)
- # ax3 = plt.subplot(2,2,3)
- # ax4 = plt.subplot(4,1,4)
- #ax2 = plt.subplot(3,3,2)
-
- # Add subplots to the grid
- ax = fig.add_subplot(gs[0, :])
- #ax1 = fig.add_subplot(gs[2, 0])
- # ax2 = fig.add_subplot(gs[2, :]) # Subplot at the top-right position
- # fig, ax = plt.subplots(1,1,figsize=(10,12))
- ax.axis('off')
-
- width = 0.08
- height = width*2.45
- if df_summ_player['launch_speed'].isna().values[0]:
- df_summ_player['sweet_spot_percent'] = np.nan
- df_summ_player['barrel_percent'] = np.nan
- df_summ_player['hard_hit_percent'] = np.nan
- if df_summ_player['launch_speed'].isna().values[0]:
- df_summ_player_pct['sweet_spot_percent'] = np.nan
- df_summ_player_pct['barrel_percent'] = np.nan
- df_summ_player_pct['hard_hit_percent'] = np.nan
- # x = 0.1
- # y = 0.9
- for cat in range(len(column_list)):
-
- # if cat < len(column_list)/2:
- x_adjust, y_adjust =(0.85/7*8)*cat/8+0.075 - (0.85/7*8)*math.floor((cat)/8), 0.45-math.floor((cat)/8)/3.2
-
- # else:
- # x_adjust, y_adjust = (cat-len(column_list)/2)*(1.7/(math.ceil((len(column_list)-1))))+0.1, 0.5
- #print( x_adjust, y_adjust)
- if sum(df_summ_player[column_list[cat]].isna()) < 1:
- print(f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}')
- ax.text(s = f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}'.format().strip(),
-
- x = x_adjust,
- y = y_adjust,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 16,
- ha='center',
- va='center')
-
- if stat_plot_dict[column_list[cat]]['flip']:
-
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum_r))
- ax.add_patch(bbox)
-
-
- else:
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum))
- ax.add_patch(bbox)
- else:
- print(f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}')
- ax.text(s = f'{df_summ_player[column_list[cat]].fillna("N/A").values[0]}',
-
- x = x_adjust,
- y = y_adjust,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- if stat_plot_dict[column_list[cat]]['flip']:
-
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum_r))
- ax.add_patch(bbox)
-
-
- else:
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum))
- ax.add_patch(bbox)
-
- ax.text(s = stat_plot_dict[column_list[cat]]['name'],
-
- x = x_adjust,
- y = y_adjust-0.14,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 12,
- ha='center',
- va='center')
-
- ax.text(s = f"{player_bio['people'][0]['fullName']}",
-
- x = 0.5,
- y = 0.95,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 28,
- ha='center',
- va='center')
- if 'parentOrgId' in player_bio['people'][0]['currentTeam']:
-
- ax.text(s = f"{player_bio['people'][0]['primaryPosition']['abbreviation']}, {mlb_teams[mlb_teams['team_id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['franchise'].values[0]}",
-
- x = 0.5,
- y = 0.85,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- else: ax.text(s = f"{player_bio['people'][0]['primaryPosition']['abbreviation']}, {player_bio['people'][0]['currentTeam']['name']}",
-
- x = 0.5,
- y = 0.85,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- ax.text(s =
- f"B/T: {player_bio['people'][0]['batSide']['code']}/"
- f"{player_bio['people'][0]['pitchHand']['code']} "
- f"{player_bio['people'][0]['height']}/"
- f"{player_bio['people'][0]['weight']}",
-
- x = 0.5,
- y = 0.785,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- ax.text(s =
-
- f"DOB: {player_bio['people'][0]['birthDate']} "
- f"Age: {player_bio['people'][0]['currentAge']}",
- x = 0.5,
- y = 0.72,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
- if sport_id_input == 1:
- try:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/{batter_select}/headshot/67/current.png'
- test_mage = plt.imread(url)
- except urllib.error.HTTPError as err:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/1/headshot/67/current.png'
-
- else:
- try:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/c_fill,g_auto/w_180/v1/people/{batter_select}/headshot/milb/current.png'
- test_mage = plt.imread(url)
- except urllib.error.HTTPError as err:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/1/headshot/67/current.png'
- im = plt.imread(url)
- # response = requests.get(url)
- # im = Image.open(BytesIO(response.content), cmap='viridis')
- # im = plt.imread(np.array(PIL.Image.open(urllib.request.urlopen(url))))
-
- # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- imagebox = OffsetImage(im, zoom = 0.35)
- ab = AnnotationBbox(imagebox, (0.125, 0.8), frameon = False)
- ax.add_artist(ab)
-
- if 'parentOrgId' in player_bio['people'][0]['currentTeam']:
- url = team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0]
-
- im = plt.imread(url)
- # response = requests.get(url)
- # im = Image.open(BytesIO(response.content))
- # im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0])
- # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- imagebox = OffsetImage(im, zoom = 0.25)
- ab = AnnotationBbox(imagebox, (0.875, 0.8), frameon = False)
- ax.add_artist(ab)
-
- else:
- url = team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['id']]['imageLink'].values[0]
- im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['id']]['imageLink'].values[0])
-
- # im = plt.imread(url)
- # response = requests.get(url)
- # im = Image.open(BytesIO(response.content))
- #im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0])
-
- # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- imagebox = OffsetImage(im, zoom = 0.25)
- ab = AnnotationBbox(imagebox, (0.875, 0.8), frameon = False)
- ax.add_artist(ab)
-
- ax.text(s = f'2023 {dict_level[sport_id_input]} Metrics',
-
- x = 0.5,
- y = 0.62,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 20,
- ha='center',
- va='center')
-
- df_plot = df_summ_batter_pitch[column_list_pitch].xs([batter_select,df_summ_update.xs(batter_select,level=0).index[0]]).sort_values('pitches',ascending=False)
- df_plot = df_plot[df_plot['pitches'] > 0]
-
- df_plot_pct = df_summ_batter_pitch_pct[column_list_pitch].xs([batter_select,df_summ_update.xs(batter_select,level=0).index[0]]).sort_values('pitches',ascending=False)#.dropna()
-
- value = 1
- # Normalize the value
- colormap = plt.get_cmap(cmap_sum)
- colormap_r = plt.get_cmap(cmap_sum_r)
- norm = Normalize(vmin=0, vmax=1)
-
-
-
- col_5_colour = [colormap_r(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['chase_percent']))]
- col_4_colour = [colormap_r(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['whiff_rate']))]
- col_3_colour = [colormap(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['woba_percent_contact']))]
- col_2_colour = ['white']*len(df_summ_batter_pitch_pct_rank)
- col_1_colour = ['white']*len(df_summ_batter_pitch_pct_rank)
- colour_df = pd.DataFrame(data=[col_1_colour,col_2_colour,col_3_colour,col_4_colour,col_5_colour]).T.values
-
- ax_table = fig.add_subplot(gs[2, 1:-1])
- ax_table.axis('off')
- print(colour_df)
- print(df_plot)
- table = ax_table.table(cellText=df_plot.values, colLabels=[stat_plot_dict[x]['name'] for x in df_plot.columns],rowLabels=df_plot.index, cellLoc='center',
- bbox=[0.12, 0.0, 0.88, 1],colWidths=[0.03]+[0.03]*(len(df_plot.columns)),
- loc='center',cellColours=colour_df)
- ax_table.text(x=0.5,y=1.1,s='Metrics By Pitch Type',ha='center',fontdict={ 'size': 12},fontname='arial')
-
- w, h = table[0,1].get_width(), table[0,1].get_height()
- table.add_cell(0, -1, w,h, text='Pitch Type')
- min_font_size = 12
- # Set table properties
- table.auto_set_font_size(False)
- table.set_fontsize(min_font_size)
- #table.set_fontname('arial')
- table.scale(1, len(df_plot)*0.3)
-
-
- for n_col in range(0,len(df_plot.columns)):
- #print(df_plot.columns[n_col],f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}")
- format_col = df_plot[df_plot.columns[n_col]].astype(str)
- n_c = 0
- for cell in table.get_celld().values():
- # print([cell.get_text().get_text()],format_col.astype(str).values)
- if cell.get_text().get_text() in format_col.astype(str).values:
-
-
- #print(cell.get_text().get_text() in format_col.astype(str).values)
- cell.get_text().set_text(f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}".format(float(cell.get_text().get_text())))
- elif cell.get_text().get_text()[:-2] in format_col.astype(str).values:
- cell.get_text().set_text(f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}".format(float(cell.get_text().get_text())))
- n_c = n_c + 1
-
- stat_1 = input.stat_1()
- window_width_1 = input.window_1()
- stat_2 = input.stat_2()
- window_width_2 = input.window_2()
- stat_3 = input.stat_3()
- window_width_3 = input.window_3()
-
-
- inset_ax = ax = fig.add_subplot(gs[3, 1])
- rolling_plot(stat=stat_1,window_width=window_width_1,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- inset_ax = ax = fig.add_subplot(gs[3, 2])
- rolling_plot(stat=stat_2,window_width=window_width_2,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- inset_ax = ax = fig.add_subplot(gs[3, 3])
- rolling_plot(stat=stat_3,window_width=window_width_3,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- ax_bot = ax = fig.add_subplot(gs[4, :])
-
- ax_bot.text(x=0.05,y=-0.5,s='By: @TJStats',ha='left',fontdict={ 'size': 14},fontname='arial')
- ax_bot.text(x=1-0.05,y=-0.5,s='Data: MLB',ha='right',fontdict={ 'size': 14},fontname='arial')
- ax_bot.axis('off')
-
-
- ax_cbar = fig.add_subplot(gs[1,1:-1])
-
- cb = matplotlib.colorbar.ColorbarBase(ax_cbar, orientation='horizontal',
- cmap=cmap_sum)
- #ax_cbar.axis('off')
- ax_cbar.text(x=0.5,y=1.2,s='Colour Scale - Percentiles',ha='center',fontdict={ 'size': 12},fontname='arial')
- ax_cbar.text(s='0%',x=0.01,y=0.5,va='center',ha='left')
- ax_cbar.text(s='100%',x=0.99,y=0.5,va='center',ha='right')
- # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- ax_cbar.set_xticks([])
- ax_cbar.set_yticks([])
- ax_cbar.set_xticklabels([])
- ax_cbar.set_yticklabels([])
-
- # Display only the outline of the axis
- for spine in ax_cbar.spines.values():
- spine.set_visible(True) # Show only the outline
- spine.set_color('black') # Set the color to black
-
- # fig.set_facecolor('#ffffff')
-
- return fig.tight_layout()
-
-
-
- return plot_card(sport_id_input=sport_id_input,
- batter_select=batter_select,
- df_roll=df_roll,
- df_summ_player=df_summ_player,
- df_summ_batter_pitch_pct=df_summ_batter_pitch_pct,
- )
- @output
- @render.plot(alt="AA Plot")
- @reactive.event(input.go, ignore_none=False)
- def aa_plot():
- ### Iniput data for the level
- #time.sleep(2)
- df_update = df_aa_update.copy()
- df_summ_update = df_summ_aa_update.copy()
- df_summ_avg_update = df_summ_avg_aa_update.copy()
-
- if len(input.player_id()) < 1:
- fig, ax = plt.subplots(1,1,figsize=(10,10))
- ax.text(s='Please Select a Batter',x=0.5,y=0.5, ha='center')
- ax.axis('off')
- return fig
-
-
- batter_select = int(input.player_id())
- sport_id_input = 12
- df_roll = df_update[df_update['batter_id']==batter_select]
- if len(df_roll) == 0:
- fig, ax = plt.subplots(1,1,figsize=(10,10))
- ax.text(s='Card is Generating',x=0.5,y=0.5, ha='center')
- ax.axis('off')
- return fig
-
-
- df_summ_filter = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[0]
- df_summ_filter_pct = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[1]
- df_summ_player = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[2]
- df_summ_player_pct = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[3]
-
- df_summ_batter_pitch = df_summ_batter_pitch_up(df= df_update).set_index(['batter_id','batter_name','pitch_category'])
-
-
- df_summ_batter_pitch_pct = df_summ_batter_pitch.loc[df_summ_filter.index.get_level_values(0)]
- df_summ_batter_pitch_pct = df_summ_batter_pitch_pct[df_summ_batter_pitch_pct['pitches']>0]
- df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct.groupby(level='pitch_category').apply(lambda x: x.rank(pct=True)).xs(batter_select,level=0)
-
- df_summ_batter_pitch_pct_rank['pitch_count'] = df_summ_batter_pitch_pct_rank.index.get_level_values(1).map(df_summ_batter_pitch.xs(batter_select,level=0).reset_index().set_index('pitch_category')['pitches'].to_dict())
- df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct_rank.sort_values('pitch_count',ascending=False)
- #df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct_rank.dropna()
- def get_color(value, vmin, vmax, cmap_name=cmap_sum):
- # Normalize the value within the range [0, 1]
- normalized_value = (value - vmin) / (vmax - vmin)
-
- # Get the colormap
- cmap = plt.get_cmap(cmap_name)
-
- # Map the normalized value to a color in the colormap
- color = cmap(normalized_value)
-
- # Convert the color from RGBA to hexadecimal format
- hex_color = mcolors.rgb2hex(color)
-
- return hex_color
-
- def get_players(sport_id=1):
- player_data = requests.get(url=f'https://statsapi.mlb.com/api/v1/sports/{sport_id}/players').json()
-
- #Select relevant data that will help distinguish players from one another
- fullName_list = [x['fullName'] for x in player_data['people']]
- id_list = [x['id'] for x in player_data['people']]
- position_list = [x['primaryPosition']['abbreviation'] for x in player_data['people']]
- team_list = [x['currentTeam']['id']for x in player_data['people']]
- age_list = [x['currentAge']for x in player_data['people']]
-
- player_df = pd.DataFrame(data={'player_id':id_list,
- 'name':fullName_list,
- 'position':position_list,
- 'team':team_list,
- 'age':age_list})
- return player_df
-
- def get_teams():
- teams = requests.get(url='https://statsapi.mlb.com/api/v1/teams/').json()
- #Select only teams that are at the MLB level
- # mlb_teams_city = [x['franchiseName'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_name = [x['teamName'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_franchise = [x['name'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_id = [x['id'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_abb = [x['abbreviation'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
-
- mlb_teams_city = [x['franchiseName'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_name = [x['teamName'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_franchise = [x['name'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_id = [x['id'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_abb = [x['abbreviation'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_parent_id = [x['parentOrgId'] if 'parentOrgId' in x else None for x in teams['teams']]
- mlb_teams_parent = [x['parentOrgName'] if 'parentOrgName' in x else None for x in teams['teams']]
- mlb_teams_league_id = [x['league']['id'] if 'id' in x['league'] else None for x in teams['teams']]
- mlb_teams_league_name = [x['league']['name'] if 'name' in x['league'] else None for x in teams['teams']]
-
-
-
- #Create a dataframe of all the teams
- mlb_teams_df = pd.DataFrame(data={'team_id':mlb_teams_id,
- 'city':mlb_teams_franchise,
- 'name':mlb_teams_name,
- 'franchise':mlb_teams_franchise,
- 'abbreviation':mlb_teams_abb,
- 'parent_org_id':mlb_teams_parent_id,
- 'parent_org':mlb_teams_parent,
- 'league_id':mlb_teams_league_id,
- 'league_name':mlb_teams_league_name
-
- }).drop_duplicates().dropna(subset=['team_id']).reset_index(drop=True).sort_values('team_id')
-
- mlb_teams_df.loc[mlb_teams_df['parent_org_id'].isnull(),'parent_org_id'] = mlb_teams_df.loc[mlb_teams_df['parent_org_id'].isnull(),'team_id']
- mlb_teams_df.loc[mlb_teams_df['parent_org'].isnull(),'parent_org'] = mlb_teams_df.loc[mlb_teams_df['parent_org'].isnull(),'franchise']
-
-
- mlb_teams_df['parent_org_abbreviation'] = mlb_teams_df['parent_org_id'].map(mlb_teams_df.set_index('team_id')['abbreviation'].to_dict())
-
- mlb_teams_df = pd.concat([mlb_teams_df, pd.DataFrame({'team_id': 11,
- 'city': 'Major League Baseball',
- 'name': 'Major League Baseball',
- 'franchise': 'Free Agent',
- 'abbreviation': 'MLB',
- 'parent_org_id': 11,
- 'parent_org': 'Major League Baseball',
- 'league_id': 1.0,
- 'league_name': 'Major League Baseball',
- 'parent_org_abbreviation': 'MLB'},index=[0])]).reset_index(drop=True)
-
- #mlb_teams_df.loc[mlb_teams_df.franchise.isin(mlb_teams_df.parent_org.unique()),'parent_org'] = mlb_teams_df.loc[mlb_teams_df.franchise.isin(mlb_teams_df.parent_org.unique()),'franchise']
-
- return mlb_teams_df
-
- def rolling_plot(stat='k_percent',window_width=100,ax=0,df_r=df_roll,df_r_summ_avg=pd.DataFrame(),stat_plot_dict_rolling=stat_plot_dict_rolling):
- plot = sns.lineplot(x=range(window_width,len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]>0])+1),
- y=df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1].fillna(0).rolling(window=window_width)[stat_plot_dict_rolling[stat]['y']].sum().dropna()/window_width,
- ax=ax,
- color="#FFB000",
- zorder=10)
-
-
-
- # ["#0C7BDC","#FFFFFF","#FFB000"])
- ax.set_xlim(window_width,len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]))
- ax.set_xlabel(stat_plot_dict_rolling[stat]['x_label'],fontsize=8)
- ax.set_ylabel(stat_plot_dict_rolling[stat]['name'],fontsize=8)
-
- ax.hlines(df_r_summ_avg[stat_plot_dict_rolling[stat]['y']]/df_r_summ_avg[stat_plot_dict_rolling[stat]['div']],
- xmin=window_width,
- xmax=len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]),
- color="#0C7BDC",linestyles='-.')
- ax.hlines(sum(df_r[stat_plot_dict_rolling[stat]['y']].dropna())/sum(df_r[stat_plot_dict_rolling[stat]['div']].dropna()),
- xmin=window_width,
- xmax=len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]),
- color="#FFB000",linestyles='--')
- #print(sum(df_r[stat_plot_dict_rolling[stat]['y']].dropna())/sum(df_r[stat_plot_dict_rolling[stat]['div']].dropna()))
- ax.tick_params(axis='x', labelsize=8) # Set x-axis ticks size
- ax.tick_params(axis='y', labelsize=8) # Set y-axis ticks size
- ax.set_title(f"{window_width} {stat_plot_dict_rolling[stat]['x_label']} Rolling {stat_plot_dict_rolling[stat]['name']}",fontsize=8)
- ax.set_ylim(stat_plot_dict_rolling[stat]['y_min'],stat_plot_dict_rolling[stat]['y_max'])
- ax.grid(True,alpha=0.2)
-
-
- if stat_plot_dict_rolling[stat]['form'] == '3f':
- ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('{x:.3f}'))
-
- elif stat_plot_dict_rolling[stat]['form'] == '1f':
- ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('{x:.1f}'))
-
- elif stat_plot_dict_rolling[stat]['form'] == '1%':
- ax.yaxis.set_major_formatter(mtick.PercentFormatter(1))
-
- return plot
-
- dict_level = {1:'MLB',
- 11:'MiLB AAA',
- 12:'MiLB AA',
- 13:'MiLB High-A',
- 14:'MiLB A'}
-
- def plot_card(sport_id_input=sport_id_input,
- batter_select=batter_select,
- df_roll=df_roll,
- df_summ_player=df_summ_player,
- df_summ_update = df_summ_update,
- df_summ_batter_pitch_pct=df_summ_batter_pitch_pct,
- ):
-
- #player_df = get_players(sport_id=sport_id_input)
- mlb_teams = get_teams()
- team_logos = pd.read_csv('team_logos.csv')
- if sport_id_input == 1:
- player_bio = requests.get(f'https://statsapi.mlb.com/api/v1/people?personIds={batter_select}&appContext=majorLeague&hydrate=currentTeam').json()
- else:
- player_bio = requests.get(f'https://statsapi.mlb.com/api/v1/people?personIds={batter_select}&appContext=minorLeague&hydrate=currentTeam').json()
-
- fig = plt.figure(figsize=(10, 10))#,dpi=600)
- plt.rcParams.update({'figure.autolayout': True})
- fig.set_facecolor('white')
- sns.set_theme(style="whitegrid", palette="pastel")
- from matplotlib.gridspec import GridSpec
- gs = GridSpec(5, 5, width_ratios=[0.2,1,1,1,0.2], height_ratios=[0.6,0.05,0.15,.30,0.025])
- #gs.update(hspace=0, wspace=0)
-
- # gs.update(left=0.1,right=0.9,top=0.97,bottom=0.03,wspace=0.3,hspace=0.09)
-
- # ax1 = plt.subplot(4,1,1)
- # ax2 = plt.subplot(2,2,2)
- # ax3 = plt.subplot(2,2,3)
- # ax4 = plt.subplot(4,1,4)
- #ax2 = plt.subplot(3,3,2)
-
- # Add subplots to the grid
- ax = fig.add_subplot(gs[0, :])
- #ax1 = fig.add_subplot(gs[2, 0])
- # ax2 = fig.add_subplot(gs[2, :]) # Subplot at the top-right position
- # fig, ax = plt.subplots(1,1,figsize=(10,12))
- ax.axis('off')
-
- width = 0.08
- height = width*2.45
- if df_summ_player['launch_speed'].isna().values[0]:
- df_summ_player['sweet_spot_percent'] = np.nan
- df_summ_player['barrel_percent'] = np.nan
- df_summ_player['hard_hit_percent'] = np.nan
- if df_summ_player['launch_speed'].isna().values[0]:
- df_summ_player_pct['sweet_spot_percent'] = np.nan
- df_summ_player_pct['barrel_percent'] = np.nan
- df_summ_player_pct['hard_hit_percent'] = np.nan
- # x = 0.1
- # y = 0.9
- for cat in range(len(column_list)):
-
- # if cat < len(column_list)/2:
- x_adjust, y_adjust =(0.85/7*8)*cat/8+0.075 - (0.85/7*8)*math.floor((cat)/8), 0.45-math.floor((cat)/8)/3.2
-
- # else:
- # x_adjust, y_adjust = (cat-len(column_list)/2)*(1.7/(math.ceil((len(column_list)-1))))+0.1, 0.5
- #print( x_adjust, y_adjust)
- if sum(df_summ_player[column_list[cat]].isna()) < 1:
- print(f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}')
- ax.text(s = f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}'.format().strip(),
-
- x = x_adjust,
- y = y_adjust,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 16,
- ha='center',
- va='center')
-
- if stat_plot_dict[column_list[cat]]['flip']:
-
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum_r))
- ax.add_patch(bbox)
-
-
- else:
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum))
- ax.add_patch(bbox)
- else:
- print(f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}')
- ax.text(s = f'{df_summ_player[column_list[cat]].fillna("N/A").values[0]}',
-
- x = x_adjust,
- y = y_adjust,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- if stat_plot_dict[column_list[cat]]['flip']:
-
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum_r))
- ax.add_patch(bbox)
-
-
- else:
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum))
- ax.add_patch(bbox)
-
- ax.text(s = stat_plot_dict[column_list[cat]]['name'],
-
- x = x_adjust,
- y = y_adjust-0.14,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 12,
- ha='center',
- va='center')
-
- ax.text(s = f"{player_bio['people'][0]['fullName']}",
-
- x = 0.5,
- y = 0.95,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 28,
- ha='center',
- va='center')
- if 'parentOrgId' in player_bio['people'][0]['currentTeam']:
-
- ax.text(s = f"{player_bio['people'][0]['primaryPosition']['abbreviation']}, {mlb_teams[mlb_teams['team_id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['franchise'].values[0]}",
-
- x = 0.5,
- y = 0.85,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- else: ax.text(s = f"{player_bio['people'][0]['primaryPosition']['abbreviation']}, {player_bio['people'][0]['currentTeam']['name']}",
-
- x = 0.5,
- y = 0.85,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- ax.text(s =
- f"B/T: {player_bio['people'][0]['batSide']['code']}/"
- f"{player_bio['people'][0]['pitchHand']['code']} "
- f"{player_bio['people'][0]['height']}/"
- f"{player_bio['people'][0]['weight']}",
-
- x = 0.5,
- y = 0.785,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- ax.text(s =
-
- f"DOB: {player_bio['people'][0]['birthDate']} "
- f"Age: {player_bio['people'][0]['currentAge']}",
- x = 0.5,
- y = 0.72,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
- if sport_id_input == 1:
- try:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/{batter_select}/headshot/67/current.png'
- test_mage = plt.imread(url)
- except urllib.error.HTTPError as err:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/1/headshot/67/current.png'
-
- else:
- try:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/c_fill,g_auto/w_180/v1/people/{batter_select}/headshot/milb/current.png'
- test_mage = plt.imread(url)
- except urllib.error.HTTPError as err:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/1/headshot/67/current.png'
- im = plt.imread(url)
- # response = requests.get(url)
- # im = Image.open(BytesIO(response.content), cmap='viridis')
- # im = plt.imread(np.array(PIL.Image.open(urllib.request.urlopen(url))))
-
- # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- imagebox = OffsetImage(im, zoom = 0.35)
- ab = AnnotationBbox(imagebox, (0.125, 0.8), frameon = False)
- ax.add_artist(ab)
-
- if 'parentOrgId' in player_bio['people'][0]['currentTeam']:
- url = team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0]
-
- im = plt.imread(url)
- # response = requests.get(url)
- # im = Image.open(BytesIO(response.content))
- # im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0])
- # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- imagebox = OffsetImage(im, zoom = 0.25)
- ab = AnnotationBbox(imagebox, (0.875, 0.8), frameon = False)
- ax.add_artist(ab)
-
- else:
- url = team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['id']]['imageLink'].values[0]
- im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['id']]['imageLink'].values[0])
-
- # im = plt.imread(url)
- # response = requests.get(url)
- # im = Image.open(BytesIO(response.content))
- #im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0])
-
- # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- imagebox = OffsetImage(im, zoom = 0.25)
- ab = AnnotationBbox(imagebox, (0.875, 0.8), frameon = False)
- ax.add_artist(ab)
-
- ax.text(s = f'2023 {dict_level[sport_id_input]} Metrics',
-
- x = 0.5,
- y = 0.62,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 20,
- ha='center',
- va='center')
-
- df_plot = df_summ_batter_pitch[column_list_pitch].xs([batter_select,df_summ_update.xs(batter_select,level=0).index[0]]).sort_values('pitches',ascending=False)#.dropna()
- df_plot = df_plot[df_plot['pitches'] > 0]
-
- df_plot_pct = df_summ_batter_pitch_pct[column_list_pitch].xs([batter_select,df_summ_update.xs(batter_select,level=0).index[0]]).sort_values('pitches',ascending=False)#.dropna()
-
- value = 1
- # Normalize the value
- colormap = plt.get_cmap(cmap_sum)
- colormap_r = plt.get_cmap(cmap_sum_r)
- norm = Normalize(vmin=0, vmax=1)
-
-
-
- col_5_colour = [colormap_r(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['chase_percent']))]
- col_4_colour = [colormap_r(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['whiff_rate']))]
- col_3_colour = [colormap(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['woba_percent_contact']))]
- col_2_colour = ['white']*len(df_summ_batter_pitch_pct_rank)
- col_1_colour = ['white']*len(df_summ_batter_pitch_pct_rank)
- colour_df = pd.DataFrame(data=[col_1_colour,col_2_colour,col_3_colour,col_4_colour,col_5_colour]).T.values
-
- ax_table = fig.add_subplot(gs[2, 1:-1])
- ax_table.axis('off')
- print(colour_df)
- print(df_plot)
- table = ax_table.table(cellText=df_plot.values, colLabels=[stat_plot_dict[x]['name'] for x in df_plot.columns],rowLabels=df_plot.index, cellLoc='center',
- bbox=[0.12, 0.0, 0.88, 1],colWidths=[0.03]+[0.03]*(len(df_plot.columns)),
- loc='center',cellColours=colour_df)
- ax_table.text(x=0.5,y=1.1,s='Metrics By Pitch Type',ha='center',fontdict={ 'size': 12},fontname='arial')
-
- w, h = table[0,1].get_width(), table[0,1].get_height()
- table.add_cell(0, -1, w,h, text='Pitch Type')
- min_font_size = 12
- # Set table properties
- table.auto_set_font_size(False)
- table.set_fontsize(min_font_size)
- #table.set_fontname('arial')
- table.scale(1, len(df_plot)*0.3)
-
-
- for n_col in range(0,len(df_plot.columns)):
- #print(df_plot.columns[n_col],f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}")
- format_col = df_plot[df_plot.columns[n_col]].astype(str)
- n_c = 0
- for cell in table.get_celld().values():
- # print([cell.get_text().get_text()],format_col.astype(str).values)
- if cell.get_text().get_text() in format_col.astype(str).values:
-
-
- #print(cell.get_text().get_text() in format_col.astype(str).values)
- cell.get_text().set_text(f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}".format(float(cell.get_text().get_text())))
- elif cell.get_text().get_text()[:-2] in format_col.astype(str).values:
- cell.get_text().set_text(f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}".format(float(cell.get_text().get_text())))
- n_c = n_c + 1
-
- stat_1 = input.stat_1()
- window_width_1 = input.window_1()
- stat_2 = input.stat_2()
- window_width_2 = input.window_2()
- stat_3 = input.stat_3()
- window_width_3 = input.window_3()
-
-
- inset_ax = ax = fig.add_subplot(gs[3, 1])
- rolling_plot(stat=stat_1,window_width=window_width_1,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- inset_ax = ax = fig.add_subplot(gs[3, 2])
- rolling_plot(stat=stat_2,window_width=window_width_2,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- inset_ax = ax = fig.add_subplot(gs[3, 3])
- rolling_plot(stat=stat_3,window_width=window_width_3,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- ax_bot = ax = fig.add_subplot(gs[4, :])
-
- ax_bot.text(x=0.05,y=-0.5,s='By: @TJStats',ha='left',fontdict={ 'size': 14},fontname='arial')
- ax_bot.text(x=1-0.05,y=-0.5,s='Data: MLB',ha='right',fontdict={ 'size': 14},fontname='arial')
- ax_bot.axis('off')
-
-
- ax_cbar = fig.add_subplot(gs[1,1:-1])
-
- cb = matplotlib.colorbar.ColorbarBase(ax_cbar, orientation='horizontal',
- cmap=cmap_sum)
- #ax_cbar.axis('off')
- ax_cbar.text(x=0.5,y=1.2,s='Colour Scale - Percentiles',ha='center',fontdict={ 'size': 12},fontname='arial')
- ax_cbar.text(s='0%',x=0.01,y=0.5,va='center',ha='left')
- ax_cbar.text(s='100%',x=0.99,y=0.5,va='center',ha='right')
- # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- ax_cbar.set_xticks([])
- ax_cbar.set_yticks([])
- ax_cbar.set_xticklabels([])
- ax_cbar.set_yticklabels([])
-
- # Display only the outline of the axis
- for spine in ax_cbar.spines.values():
- spine.set_visible(True) # Show only the outline
- spine.set_color('black') # Set the color to black
-
- # fig.set_facecolor('#ffffff')
-
- return fig.tight_layout()
-
-
-
- return plot_card(sport_id_input=sport_id_input,
- batter_select=batter_select,
- df_roll=df_roll,
- df_summ_player=df_summ_player,
- df_summ_batter_pitch_pct=df_summ_batter_pitch_pct,
- )
- @output
- @render.plot(alt="High-A Plot")
- @reactive.event(input.go, ignore_none=False)
- def ha_plot():
- ### Iniput data for the level
- #time.sleep(2)
- df_update = df_ha_update.copy()
- df_summ_update = df_summ_ha_update.copy()
- df_summ_avg_update = df_summ_avg_a_update.copy()
- if len(input.player_id()) < 1:
- fig, ax = plt.subplots(1,1,figsize=(10,10))
- ax.text(s='Please Select a Batter',x=0.5,y=0.5, ha='center')
- ax.axis('off')
- return fig
-
-
- batter_select = int(input.player_id())
- sport_id_input = 13
- df_roll = df_update[df_update['batter_id']==batter_select]
- if len(df_roll) == 0:
- fig, ax = plt.subplots(1,1,figsize=(10,10))
- ax.text(s='Card is Generating',x=0.5,y=0.5, ha='center')
- ax.axis('off')
- return fig
-
-
- df_summ_filter = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[0]
- df_summ_filter_pct = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[1]
- df_summ_player = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[2]
- df_summ_player_pct = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[3]
-
- df_summ_batter_pitch = df_summ_batter_pitch_up(df= df_update).set_index(['batter_id','batter_name','pitch_category'])
-
-
- df_summ_batter_pitch_pct = df_summ_batter_pitch.loc[df_summ_filter.index.get_level_values(0)]
- df_summ_batter_pitch_pct = df_summ_batter_pitch_pct[df_summ_batter_pitch_pct['pitches']>0]
- df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct.groupby(level='pitch_category').apply(lambda x: x.rank(pct=True)).xs(batter_select,level=0)
-
- df_summ_batter_pitch_pct_rank['pitch_count'] = df_summ_batter_pitch_pct_rank.index.get_level_values(1).map(df_summ_batter_pitch.xs(batter_select,level=0).reset_index().set_index('pitch_category')['pitches'].to_dict())
- df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct_rank.sort_values('pitch_count',ascending=False)
- #df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct_rank.dropna()
- def get_color(value, vmin, vmax, cmap_name=cmap_sum):
- # Normalize the value within the range [0, 1]
- normalized_value = (value - vmin) / (vmax - vmin)
-
- # Get the colormap
- cmap = plt.get_cmap(cmap_name)
-
- # Map the normalized value to a color in the colormap
- color = cmap(normalized_value)
-
- # Convert the color from RGBA to hexadecimal format
- hex_color = mcolors.rgb2hex(color)
-
- return hex_color
-
- def get_players(sport_id=1):
- player_data = requests.get(url=f'https://statsapi.mlb.com/api/v1/sports/{sport_id}/players').json()
-
- #Select relevant data that will help distinguish players from one another
- fullName_list = [x['fullName'] for x in player_data['people']]
- id_list = [x['id'] for x in player_data['people']]
- position_list = [x['primaryPosition']['abbreviation'] for x in player_data['people']]
- team_list = [x['currentTeam']['id']for x in player_data['people']]
- age_list = [x['currentAge']for x in player_data['people']]
-
- player_df = pd.DataFrame(data={'player_id':id_list,
- 'name':fullName_list,
- 'position':position_list,
- 'team':team_list,
- 'age':age_list})
- return player_df
-
- def get_teams():
- teams = requests.get(url='https://statsapi.mlb.com/api/v1/teams/').json()
- #Select only teams that are at the MLB level
- # mlb_teams_city = [x['franchiseName'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_name = [x['teamName'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_franchise = [x['name'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_id = [x['id'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_abb = [x['abbreviation'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
-
- mlb_teams_city = [x['franchiseName'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_name = [x['teamName'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_franchise = [x['name'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_id = [x['id'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_abb = [x['abbreviation'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_parent_id = [x['parentOrgId'] if 'parentOrgId' in x else None for x in teams['teams']]
- mlb_teams_parent = [x['parentOrgName'] if 'parentOrgName' in x else None for x in teams['teams']]
- mlb_teams_league_id = [x['league']['id'] if 'id' in x['league'] else None for x in teams['teams']]
- mlb_teams_league_name = [x['league']['name'] if 'name' in x['league'] else None for x in teams['teams']]
-
-
-
- #Create a dataframe of all the teams
- mlb_teams_df = pd.DataFrame(data={'team_id':mlb_teams_id,
- 'city':mlb_teams_franchise,
- 'name':mlb_teams_name,
- 'franchise':mlb_teams_franchise,
- 'abbreviation':mlb_teams_abb,
- 'parent_org_id':mlb_teams_parent_id,
- 'parent_org':mlb_teams_parent,
- 'league_id':mlb_teams_league_id,
- 'league_name':mlb_teams_league_name
-
- }).drop_duplicates().dropna(subset=['team_id']).reset_index(drop=True).sort_values('team_id')
-
- mlb_teams_df.loc[mlb_teams_df['parent_org_id'].isnull(),'parent_org_id'] = mlb_teams_df.loc[mlb_teams_df['parent_org_id'].isnull(),'team_id']
- mlb_teams_df.loc[mlb_teams_df['parent_org'].isnull(),'parent_org'] = mlb_teams_df.loc[mlb_teams_df['parent_org'].isnull(),'franchise']
-
-
- mlb_teams_df['parent_org_abbreviation'] = mlb_teams_df['parent_org_id'].map(mlb_teams_df.set_index('team_id')['abbreviation'].to_dict())
-
- mlb_teams_df = pd.concat([mlb_teams_df, pd.DataFrame({'team_id': 11,
- 'city': 'Major League Baseball',
- 'name': 'Major League Baseball',
- 'franchise': 'Free Agent',
- 'abbreviation': 'MLB',
- 'parent_org_id': 11,
- 'parent_org': 'Major League Baseball',
- 'league_id': 1.0,
- 'league_name': 'Major League Baseball',
- 'parent_org_abbreviation': 'MLB'},index=[0])]).reset_index(drop=True)
-
- #mlb_teams_df.loc[mlb_teams_df.franchise.isin(mlb_teams_df.parent_org.unique()),'parent_org'] = mlb_teams_df.loc[mlb_teams_df.franchise.isin(mlb_teams_df.parent_org.unique()),'franchise']
-
- return mlb_teams_df
-
- def rolling_plot(stat='k_percent',window_width=100,ax=0,df_r=df_roll,df_r_summ_avg=pd.DataFrame(),stat_plot_dict_rolling=stat_plot_dict_rolling):
- plot = sns.lineplot(x=range(window_width,len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]>0])+1),
- y=df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1].fillna(0).rolling(window=window_width)[stat_plot_dict_rolling[stat]['y']].sum().dropna()/window_width,
- ax=ax,
- color="#FFB000",
- zorder=10)
-
-
-
- # ["#0C7BDC","#FFFFFF","#FFB000"])
- ax.set_xlim(window_width,len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]))
- ax.set_xlabel(stat_plot_dict_rolling[stat]['x_label'],fontsize=8)
- ax.set_ylabel(stat_plot_dict_rolling[stat]['name'],fontsize=8)
-
- ax.hlines(df_r_summ_avg[stat_plot_dict_rolling[stat]['y']]/df_r_summ_avg[stat_plot_dict_rolling[stat]['div']],
- xmin=window_width,
- xmax=len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]),
- color="#0C7BDC",linestyles='-.')
- ax.hlines(sum(df_r[stat_plot_dict_rolling[stat]['y']].dropna())/sum(df_r[stat_plot_dict_rolling[stat]['div']].dropna()),
- xmin=window_width,
- xmax=len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]),
- color="#FFB000",linestyles='--')
- #print(sum(df_r[stat_plot_dict_rolling[stat]['y']].dropna())/sum(df_r[stat_plot_dict_rolling[stat]['div']].dropna()))
- ax.tick_params(axis='x', labelsize=8) # Set x-axis ticks size
- ax.tick_params(axis='y', labelsize=8) # Set y-axis ticks size
- ax.set_title(f"{window_width} {stat_plot_dict_rolling[stat]['x_label']} Rolling {stat_plot_dict_rolling[stat]['name']}",fontsize=8)
- ax.set_ylim(stat_plot_dict_rolling[stat]['y_min'],stat_plot_dict_rolling[stat]['y_max'])
- ax.grid(True,alpha=0.2)
-
-
- if stat_plot_dict_rolling[stat]['form'] == '3f':
- ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('{x:.3f}'))
-
- elif stat_plot_dict_rolling[stat]['form'] == '1f':
- ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('{x:.1f}'))
-
- elif stat_plot_dict_rolling[stat]['form'] == '1%':
- ax.yaxis.set_major_formatter(mtick.PercentFormatter(1))
-
- return plot
-
- dict_level = {1:'MLB',
- 11:'MiLB AAA',
- 12:'MiLB AA',
- 13:'MiLB High-A',
- 14:'MiLB A'}
-
- def plot_card(sport_id_input=sport_id_input,
- batter_select=batter_select,
- df_roll=df_roll,
- df_summ_player=df_summ_player,
- df_summ_update = df_summ_update,
- df_summ_batter_pitch_pct=df_summ_batter_pitch_pct,
- ):
-
- #player_df = get_players(sport_id=sport_id_input)
- mlb_teams = get_teams()
- team_logos = pd.read_csv('team_logos.csv')
- if sport_id_input == 1:
- player_bio = requests.get(f'https://statsapi.mlb.com/api/v1/people?personIds={batter_select}&appContext=majorLeague&hydrate=currentTeam').json()
- else:
- player_bio = requests.get(f'https://statsapi.mlb.com/api/v1/people?personIds={batter_select}&appContext=minorLeague&hydrate=currentTeam').json()
-
- fig = plt.figure(figsize=(10, 10))#,dpi=600)
- plt.rcParams.update({'figure.autolayout': True})
- fig.set_facecolor('white')
- sns.set_theme(style="whitegrid", palette="pastel")
- from matplotlib.gridspec import GridSpec
- gs = GridSpec(5, 5, width_ratios=[0.2,1,1,1,0.2], height_ratios=[0.6,0.05,0.15,.30,0.025])
- #gs.update(hspace=0, wspace=0)
-
- # gs.update(left=0.1,right=0.9,top=0.97,bottom=0.03,wspace=0.3,hspace=0.09)
-
- # ax1 = plt.subplot(4,1,1)
- # ax2 = plt.subplot(2,2,2)
- # ax3 = plt.subplot(2,2,3)
- # ax4 = plt.subplot(4,1,4)
- #ax2 = plt.subplot(3,3,2)
-
- # Add subplots to the grid
- ax = fig.add_subplot(gs[0, :])
- #ax1 = fig.add_subplot(gs[2, 0])
- # ax2 = fig.add_subplot(gs[2, :]) # Subplot at the top-right position
- # fig, ax = plt.subplots(1,1,figsize=(10,12))
- ax.axis('off')
-
- width = 0.08
- height = width*2.45
- if df_summ_player['launch_speed'].isna().values[0]:
- df_summ_player['sweet_spot_percent'] = np.nan
- df_summ_player['barrel_percent'] = np.nan
- df_summ_player['hard_hit_percent'] = np.nan
- if df_summ_player['launch_speed'].isna().values[0]:
- df_summ_player_pct['sweet_spot_percent'] = np.nan
- df_summ_player_pct['barrel_percent'] = np.nan
- df_summ_player_pct['hard_hit_percent'] = np.nan
- # x = 0.1
- # y = 0.9
- for cat in range(len(column_list)):
-
- # if cat < len(column_list)/2:
- x_adjust, y_adjust =(0.85/7*8)*cat/8+0.075 - (0.85/7*8)*math.floor((cat)/8), 0.45-math.floor((cat)/8)/3.2
-
- # else:
- # x_adjust, y_adjust = (cat-len(column_list)/2)*(1.7/(math.ceil((len(column_list)-1))))+0.1, 0.5
- #print( x_adjust, y_adjust)
- if sum(df_summ_player[column_list[cat]].isna()) < 1:
- print(f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}')
- ax.text(s = f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}'.format().strip(),
-
- x = x_adjust,
- y = y_adjust,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 16,
- ha='center',
- va='center')
-
- if stat_plot_dict[column_list[cat]]['flip']:
-
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum_r))
- ax.add_patch(bbox)
-
-
- else:
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum))
- ax.add_patch(bbox)
- else:
- print(f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}')
- ax.text(s = f'{df_summ_player[column_list[cat]].fillna("N/A").values[0]}',
-
- x = x_adjust,
- y = y_adjust,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- if stat_plot_dict[column_list[cat]]['flip']:
-
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum_r))
- ax.add_patch(bbox)
-
-
- else:
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum))
- ax.add_patch(bbox)
-
- ax.text(s = stat_plot_dict[column_list[cat]]['name'],
-
- x = x_adjust,
- y = y_adjust-0.14,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 12,
- ha='center',
- va='center')
-
- ax.text(s = f"{player_bio['people'][0]['fullName']}",
-
- x = 0.5,
- y = 0.95,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 28,
- ha='center',
- va='center')
- if 'parentOrgId' in player_bio['people'][0]['currentTeam']:
-
- ax.text(s = f"{player_bio['people'][0]['primaryPosition']['abbreviation']}, {mlb_teams[mlb_teams['team_id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['franchise'].values[0]}",
-
- x = 0.5,
- y = 0.85,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- else: ax.text(s = f"{player_bio['people'][0]['primaryPosition']['abbreviation']}, {player_bio['people'][0]['currentTeam']['name']}",
-
- x = 0.5,
- y = 0.85,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- ax.text(s =
- f"B/T: {player_bio['people'][0]['batSide']['code']}/"
- f"{player_bio['people'][0]['pitchHand']['code']} "
- f"{player_bio['people'][0]['height']}/"
- f"{player_bio['people'][0]['weight']}",
-
- x = 0.5,
- y = 0.785,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- ax.text(s =
-
- f"DOB: {player_bio['people'][0]['birthDate']} "
- f"Age: {player_bio['people'][0]['currentAge']}",
- x = 0.5,
- y = 0.72,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
- if sport_id_input == 1:
- try:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/{batter_select}/headshot/67/current.png'
- test_mage = plt.imread(url)
- except urllib.error.HTTPError as err:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/1/headshot/67/current.png'
-
- else:
- try:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/c_fill,g_auto/w_180/v1/people/{batter_select}/headshot/milb/current.png'
- test_mage = plt.imread(url)
- except urllib.error.HTTPError as err:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/1/headshot/67/current.png'
- im = plt.imread(url)
- # response = requests.get(url)
- # im = Image.open(BytesIO(response.content), cmap='viridis')
- # im = plt.imread(np.array(PIL.Image.open(urllib.request.urlopen(url))))
-
- # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- imagebox = OffsetImage(im, zoom = 0.35)
- ab = AnnotationBbox(imagebox, (0.125, 0.8), frameon = False)
- ax.add_artist(ab)
-
- if 'parentOrgId' in player_bio['people'][0]['currentTeam']:
- url = team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0]
-
- im = plt.imread(url)
- # response = requests.get(url)
- # im = Image.open(BytesIO(response.content))
- # im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0])
- # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- imagebox = OffsetImage(im, zoom = 0.25)
- ab = AnnotationBbox(imagebox, (0.875, 0.8), frameon = False)
- ax.add_artist(ab)
-
- else:
- url = team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['id']]['imageLink'].values[0]
- im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['id']]['imageLink'].values[0])
-
- # im = plt.imread(url)
- # response = requests.get(url)
- # im = Image.open(BytesIO(response.content))
- #im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0])
-
- # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- imagebox = OffsetImage(im, zoom = 0.25)
- ab = AnnotationBbox(imagebox, (0.875, 0.8), frameon = False)
- ax.add_artist(ab)
-
- ax.text(s = f'2023 {dict_level[sport_id_input]} Metrics',
-
- x = 0.5,
- y = 0.62,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 20,
- ha='center',
- va='center')
-
- df_plot = df_summ_batter_pitch[column_list_pitch].xs([batter_select,df_summ_update.xs(batter_select,level=0).index[0]]).sort_values('pitches',ascending=False)#.dropna()
- df_plot = df_plot[df_plot['pitches'] > 0]
-
- df_plot_pct = df_summ_batter_pitch_pct[column_list_pitch].xs([batter_select,df_summ_update.xs(batter_select,level=0).index[0]]).sort_values('pitches',ascending=False)#.dropna()
-
- value = 1
- # Normalize the value
- colormap = plt.get_cmap(cmap_sum)
- colormap_r = plt.get_cmap(cmap_sum_r)
- norm = Normalize(vmin=0, vmax=1)
-
-
-
- col_5_colour = [colormap_r(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['chase_percent']))]
- col_4_colour = [colormap_r(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['whiff_rate']))]
- col_3_colour = [colormap(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['woba_percent_contact']))]
- col_2_colour = ['white']*len(df_summ_batter_pitch_pct_rank)
- col_1_colour = ['white']*len(df_summ_batter_pitch_pct_rank)
- colour_df = pd.DataFrame(data=[col_1_colour,col_2_colour,col_3_colour,col_4_colour,col_5_colour]).T.values
-
- ax_table = fig.add_subplot(gs[2, 1:-1])
- ax_table.axis('off')
- print(colour_df)
- print(df_plot)
- table = ax_table.table(cellText=df_plot.values, colLabels=[stat_plot_dict[x]['name'] for x in df_plot.columns],rowLabels=df_plot.index, cellLoc='center',
- bbox=[0.12, 0.0, 0.88, 1],colWidths=[0.03]+[0.03]*(len(df_plot.columns)),
- loc='center',cellColours=colour_df)
- ax_table.text(x=0.5,y=1.1,s='Metrics By Pitch Type',ha='center',fontdict={ 'size': 12},fontname='arial')
-
- w, h = table[0,1].get_width(), table[0,1].get_height()
- table.add_cell(0, -1, w,h, text='Pitch Type')
- min_font_size = 12
- # Set table properties
- table.auto_set_font_size(False)
- table.set_fontsize(min_font_size)
- #table.set_fontname('arial')
- table.scale(1, len(df_plot)*0.3)
-
-
- for n_col in range(0,len(df_plot.columns)):
- #print(df_plot.columns[n_col],f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}")
- format_col = df_plot[df_plot.columns[n_col]].astype(str)
- n_c = 0
- for cell in table.get_celld().values():
- # print([cell.get_text().get_text()],format_col.astype(str).values)
- if cell.get_text().get_text() in format_col.astype(str).values:
-
-
- #print(cell.get_text().get_text() in format_col.astype(str).values)
- cell.get_text().set_text(f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}".format(float(cell.get_text().get_text())))
- elif cell.get_text().get_text()[:-2] in format_col.astype(str).values:
- cell.get_text().set_text(f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}".format(float(cell.get_text().get_text())))
- n_c = n_c + 1
-
- stat_1 = input.stat_1()
- window_width_1 = input.window_1()
- stat_2 = input.stat_2()
- window_width_2 = input.window_2()
- stat_3 = input.stat_3()
- window_width_3 = input.window_3()
-
-
- inset_ax = ax = fig.add_subplot(gs[3, 1])
- rolling_plot(stat=stat_1,window_width=window_width_1,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- inset_ax = ax = fig.add_subplot(gs[3, 2])
- rolling_plot(stat=stat_2,window_width=window_width_2,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- inset_ax = ax = fig.add_subplot(gs[3, 3])
- rolling_plot(stat=stat_3,window_width=window_width_3,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- ax_bot = ax = fig.add_subplot(gs[4, :])
-
- ax_bot.text(x=0.05,y=-0.5,s='By: @TJStats',ha='left',fontdict={ 'size': 14},fontname='arial')
- ax_bot.text(x=1-0.05,y=-0.5,s='Data: MLB',ha='right',fontdict={ 'size': 14},fontname='arial')
- ax_bot.axis('off')
-
-
- ax_cbar = fig.add_subplot(gs[1,1:-1])
-
- cb = matplotlib.colorbar.ColorbarBase(ax_cbar, orientation='horizontal',
- cmap=cmap_sum)
- #ax_cbar.axis('off')
- ax_cbar.text(x=0.5,y=1.2,s='Colour Scale - Percentiles',ha='center',fontdict={ 'size': 12},fontname='arial')
- ax_cbar.text(s='0%',x=0.01,y=0.5,va='center',ha='left')
- ax_cbar.text(s='100%',x=0.99,y=0.5,va='center',ha='right')
- # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- ax_cbar.set_xticks([])
- ax_cbar.set_yticks([])
- ax_cbar.set_xticklabels([])
- ax_cbar.set_yticklabels([])
-
- # Display only the outline of the axis
- for spine in ax_cbar.spines.values():
- spine.set_visible(True) # Show only the outline
- spine.set_color('black') # Set the color to black
-
- # fig.set_facecolor('#ffffff')
-
- return fig.tight_layout()
-
-
-
- return plot_card(sport_id_input=sport_id_input,
- batter_select=batter_select,
- df_roll=df_roll,
- df_summ_player=df_summ_player,
- df_summ_batter_pitch_pct=df_summ_batter_pitch_pct,
- )
- @output
- @render.plot(alt="A Plot")
- @reactive.event(input.go, ignore_none=False)
- def a_plot():
- ### Iniput data for the level
- #time.sleep(2)
- df_update = df_a_update.copy()
- df_summ_update = df_summ_a_update.copy()
- df_summ_avg_update = df_summ_avg_a_update.copy()
- if len(input.player_id()) < 1:
- fig, ax = plt.subplots(1,1,figsize=(10,10))
- ax.text(s='Please Select a Batter',x=0.5,y=0.5, ha='center')
- ax.axis('off')
- return fig
-
-
- batter_select = int(input.player_id())
- sport_id_input = 14
- df_roll = df_update[df_update['batter_id']==batter_select]
- if len(df_roll) == 0:
- fig, ax = plt.subplots(1,1,figsize=(10,10))
- ax.text(s='Card is Generating',x=0.5,y=0.5, ha='center')
- ax.axis('off')
- return fig
-
- df_summ_filter = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[0]
- df_summ_filter_pct = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[1]
- df_summ_player = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[2]
- df_summ_player_pct = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[3]
-
- df_summ_batter_pitch = df_summ_batter_pitch_up(df= df_update).set_index(['batter_id','batter_name','pitch_category'])
-
-
- df_summ_batter_pitch_pct = df_summ_batter_pitch.loc[df_summ_filter.index.get_level_values(0)]
- df_summ_batter_pitch_pct = df_summ_batter_pitch_pct[df_summ_batter_pitch_pct['pitches']>0]
- df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct.groupby(level='pitch_category').apply(lambda x: x.rank(pct=True)).xs(batter_select,level=0)
-
- df_summ_batter_pitch_pct_rank['pitch_count'] = df_summ_batter_pitch_pct_rank.index.get_level_values(1).map(df_summ_batter_pitch.xs(batter_select,level=0).reset_index().set_index('pitch_category')['pitches'].to_dict())
- df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct_rank.sort_values('pitch_count',ascending=False)
- #df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct_rank.dropna()
- def get_color(value, vmin, vmax, cmap_name=cmap_sum):
- # Normalize the value within the range [0, 1]
- normalized_value = (value - vmin) / (vmax - vmin)
-
- # Get the colormap
- cmap = plt.get_cmap(cmap_name)
-
- # Map the normalized value to a color in the colormap
- color = cmap(normalized_value)
-
- # Convert the color from RGBA to hexadecimal format
- hex_color = mcolors.rgb2hex(color)
-
- return hex_color
-
- def get_players(sport_id=1):
- player_data = requests.get(url=f'https://statsapi.mlb.com/api/v1/sports/{sport_id}/players').json()
-
- #Select relevant data that will help distinguish players from one another
- fullName_list = [x['fullName'] for x in player_data['people']]
- id_list = [x['id'] for x in player_data['people']]
- position_list = [x['primaryPosition']['abbreviation'] for x in player_data['people']]
- team_list = [x['currentTeam']['id']for x in player_data['people']]
- age_list = [x['currentAge']for x in player_data['people']]
-
- player_df = pd.DataFrame(data={'player_id':id_list,
- 'name':fullName_list,
- 'position':position_list,
- 'team':team_list,
- 'age':age_list})
- return player_df
-
- def get_teams():
- teams = requests.get(url='https://statsapi.mlb.com/api/v1/teams/').json()
- #Select only teams that are at the MLB level
- # mlb_teams_city = [x['franchiseName'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_name = [x['teamName'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_franchise = [x['name'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_id = [x['id'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # mlb_teams_abb = [x['abbreviation'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
-
- mlb_teams_city = [x['franchiseName'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_name = [x['teamName'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_franchise = [x['name'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_id = [x['id'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_abb = [x['abbreviation'] if 'franchiseName' in x else None for x in teams['teams']]
- mlb_teams_parent_id = [x['parentOrgId'] if 'parentOrgId' in x else None for x in teams['teams']]
- mlb_teams_parent = [x['parentOrgName'] if 'parentOrgName' in x else None for x in teams['teams']]
- mlb_teams_league_id = [x['league']['id'] if 'id' in x['league'] else None for x in teams['teams']]
- mlb_teams_league_name = [x['league']['name'] if 'name' in x['league'] else None for x in teams['teams']]
-
-
-
- #Create a dataframe of all the teams
- mlb_teams_df = pd.DataFrame(data={'team_id':mlb_teams_id,
- 'city':mlb_teams_franchise,
- 'name':mlb_teams_name,
- 'franchise':mlb_teams_franchise,
- 'abbreviation':mlb_teams_abb,
- 'parent_org_id':mlb_teams_parent_id,
- 'parent_org':mlb_teams_parent,
- 'league_id':mlb_teams_league_id,
- 'league_name':mlb_teams_league_name
-
- }).drop_duplicates().dropna(subset=['team_id']).reset_index(drop=True).sort_values('team_id')
-
- mlb_teams_df.loc[mlb_teams_df['parent_org_id'].isnull(),'parent_org_id'] = mlb_teams_df.loc[mlb_teams_df['parent_org_id'].isnull(),'team_id']
- mlb_teams_df.loc[mlb_teams_df['parent_org'].isnull(),'parent_org'] = mlb_teams_df.loc[mlb_teams_df['parent_org'].isnull(),'franchise']
-
-
- mlb_teams_df['parent_org_abbreviation'] = mlb_teams_df['parent_org_id'].map(mlb_teams_df.set_index('team_id')['abbreviation'].to_dict())
-
- mlb_teams_df = pd.concat([mlb_teams_df, pd.DataFrame({'team_id': 11,
- 'city': 'Major League Baseball',
- 'name': 'Major League Baseball',
- 'franchise': 'Free Agent',
- 'abbreviation': 'MLB',
- 'parent_org_id': 11,
- 'parent_org': 'Major League Baseball',
- 'league_id': 1.0,
- 'league_name': 'Major League Baseball',
- 'parent_org_abbreviation': 'MLB'},index=[0])]).reset_index(drop=True)
-
- #mlb_teams_df.loc[mlb_teams_df.franchise.isin(mlb_teams_df.parent_org.unique()),'parent_org'] = mlb_teams_df.loc[mlb_teams_df.franchise.isin(mlb_teams_df.parent_org.unique()),'franchise']
-
- return mlb_teams_df
-
- def rolling_plot(stat='k_percent',window_width=100,ax=0,df_r=df_roll,df_r_summ_avg=pd.DataFrame(),stat_plot_dict_rolling=stat_plot_dict_rolling):
- plot = sns.lineplot(x=range(window_width,len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]>0])+1),
- y=df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1].fillna(0).rolling(window=window_width)[stat_plot_dict_rolling[stat]['y']].sum().dropna()/window_width,
- ax=ax,
- color="#FFB000",
- zorder=10)
-
-
-
- # ["#0C7BDC","#FFFFFF","#FFB000"])
- ax.set_xlim(window_width,len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]))
- ax.set_xlabel(stat_plot_dict_rolling[stat]['x_label'],fontsize=8)
- ax.set_ylabel(stat_plot_dict_rolling[stat]['name'],fontsize=8)
-
- ax.hlines(df_r_summ_avg[stat_plot_dict_rolling[stat]['y']]/df_r_summ_avg[stat_plot_dict_rolling[stat]['div']],
- xmin=window_width,
- xmax=len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]),
- color="#0C7BDC",linestyles='-.')
- ax.hlines(sum(df_r[stat_plot_dict_rolling[stat]['y']].dropna())/sum(df_r[stat_plot_dict_rolling[stat]['div']].dropna()),
- xmin=window_width,
- xmax=len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]),
- color="#FFB000",linestyles='--')
- #print(sum(df_r[stat_plot_dict_rolling[stat]['y']].dropna())/sum(df_r[stat_plot_dict_rolling[stat]['div']].dropna()))
- ax.tick_params(axis='x', labelsize=8) # Set x-axis ticks size
- ax.tick_params(axis='y', labelsize=8) # Set y-axis ticks size
- ax.set_title(f"{window_width} {stat_plot_dict_rolling[stat]['x_label']} Rolling {stat_plot_dict_rolling[stat]['name']}",fontsize=8)
- ax.set_ylim(stat_plot_dict_rolling[stat]['y_min'],stat_plot_dict_rolling[stat]['y_max'])
- ax.grid(True,alpha=0.2)
-
-
- if stat_plot_dict_rolling[stat]['form'] == '3f':
- ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('{x:.3f}'))
-
- elif stat_plot_dict_rolling[stat]['form'] == '1f':
- ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('{x:.1f}'))
-
- elif stat_plot_dict_rolling[stat]['form'] == '1%':
- ax.yaxis.set_major_formatter(mtick.PercentFormatter(1))
-
- return plot
-
- dict_level = {1:'MLB',
- 11:'MiLB AAA',
- 12:'MiLB AA',
- 13:'MiLB High-A',
- 14:'MiLB A'}
-
- def plot_card(sport_id_input=sport_id_input,
- batter_select=batter_select,
- df_roll=df_roll,
- df_summ_player=df_summ_player,
- df_summ_update = df_summ_update,
- df_summ_batter_pitch_pct=df_summ_batter_pitch_pct,
- ):
-
- #player_df = get_players(sport_id=sport_id_input)
- mlb_teams = get_teams()
- team_logos = pd.read_csv('team_logos.csv')
- if sport_id_input == 1:
- player_bio = requests.get(f'https://statsapi.mlb.com/api/v1/people?personIds={batter_select}&appContext=majorLeague&hydrate=currentTeam').json()
- else:
- player_bio = requests.get(f'https://statsapi.mlb.com/api/v1/people?personIds={batter_select}&appContext=minorLeague&hydrate=currentTeam').json()
-
- fig = plt.figure(figsize=(10, 10))#,dpi=600)
- plt.rcParams.update({'figure.autolayout': True})
- fig.set_facecolor('white')
- sns.set_theme(style="whitegrid", palette="pastel")
- from matplotlib.gridspec import GridSpec
- gs = GridSpec(5, 5, width_ratios=[0.2,1,1,1,0.2], height_ratios=[0.6,0.05,0.15,.30,0.025])
- #gs.update(hspace=0, wspace=0)
-
- # gs.update(left=0.1,right=0.9,top=0.97,bottom=0.03,wspace=0.3,hspace=0.09)
-
- # ax1 = plt.subplot(4,1,1)
- # ax2 = plt.subplot(2,2,2)
- # ax3 = plt.subplot(2,2,3)
- # ax4 = plt.subplot(4,1,4)
- #ax2 = plt.subplot(3,3,2)
-
- # Add subplots to the grid
- ax = fig.add_subplot(gs[0, :])
- #ax1 = fig.add_subplot(gs[2, 0])
- # ax2 = fig.add_subplot(gs[2, :]) # Subplot at the top-right position
- # fig, ax = plt.subplots(1,1,figsize=(10,12))
- ax.axis('off')
-
- width = 0.08
- height = width*2.45
- if df_summ_player['launch_speed'].isna().values[0]:
- df_summ_player['sweet_spot_percent'] = np.nan
- df_summ_player['barrel_percent'] = np.nan
- df_summ_player['hard_hit_percent'] = np.nan
- if df_summ_player['launch_speed'].isna().values[0]:
- df_summ_player_pct['sweet_spot_percent'] = np.nan
- df_summ_player_pct['barrel_percent'] = np.nan
- df_summ_player_pct['hard_hit_percent'] = np.nan
- # x = 0.1
- # y = 0.9
- for cat in range(len(column_list)):
-
- # if cat < len(column_list)/2:
- x_adjust, y_adjust =(0.85/7*8)*cat/8+0.075 - (0.85/7*8)*math.floor((cat)/8), 0.45-math.floor((cat)/8)/3.2
-
- # else:
- # x_adjust, y_adjust = (cat-len(column_list)/2)*(1.7/(math.ceil((len(column_list)-1))))+0.1, 0.5
- #print( x_adjust, y_adjust)
- if sum(df_summ_player[column_list[cat]].isna()) < 1:
- print(f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}')
- ax.text(s = f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}'.format().strip(),
-
- x = x_adjust,
- y = y_adjust,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 16,
- ha='center',
- va='center')
-
- if stat_plot_dict[column_list[cat]]['flip']:
-
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum_r))
- ax.add_patch(bbox)
-
-
- else:
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum))
- ax.add_patch(bbox)
- else:
- print(f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}')
- ax.text(s = f'{df_summ_player[column_list[cat]].fillna("N/A").values[0]}',
-
- x = x_adjust,
- y = y_adjust,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- if stat_plot_dict[column_list[cat]]['flip']:
-
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum_r))
- ax.add_patch(bbox)
-
-
- else:
- bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum))
- ax.add_patch(bbox)
-
- ax.text(s = stat_plot_dict[column_list[cat]]['name'],
-
- x = x_adjust,
- y = y_adjust-0.14,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 12,
- ha='center',
- va='center')
-
- ax.text(s = f"{player_bio['people'][0]['fullName']}",
-
- x = 0.5,
- y = 0.95,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 28,
- ha='center',
- va='center')
- if 'parentOrgId' in player_bio['people'][0]['currentTeam']:
-
- ax.text(s = f"{player_bio['people'][0]['primaryPosition']['abbreviation']}, {mlb_teams[mlb_teams['team_id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['franchise'].values[0]}",
-
- x = 0.5,
- y = 0.85,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- else: ax.text(s = f"{player_bio['people'][0]['primaryPosition']['abbreviation']}, {player_bio['people'][0]['currentTeam']['name']}",
-
- x = 0.5,
- y = 0.85,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- ax.text(s =
- f"B/T: {player_bio['people'][0]['batSide']['code']}/"
- f"{player_bio['people'][0]['pitchHand']['code']} "
- f"{player_bio['people'][0]['height']}/"
- f"{player_bio['people'][0]['weight']}",
-
- x = 0.5,
- y = 0.785,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
-
- ax.text(s =
-
- f"DOB: {player_bio['people'][0]['birthDate']} "
- f"Age: {player_bio['people'][0]['currentAge']}",
- x = 0.5,
- y = 0.72,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 14,
- ha='center',
- va='center')
- if sport_id_input == 1:
- try:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/{batter_select}/headshot/67/current.png'
- test_mage = plt.imread(url)
- except urllib.error.HTTPError as err:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/1/headshot/67/current.png'
-
- else:
- try:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/c_fill,g_auto/w_180/v1/people/{batter_select}/headshot/milb/current.png'
- test_mage = plt.imread(url)
- except urllib.error.HTTPError as err:
- url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/1/headshot/67/current.png'
- im = plt.imread(url)
- # response = requests.get(url)
- # im = Image.open(BytesIO(response.content), cmap='viridis')
- # im = plt.imread(np.array(PIL.Image.open(urllib.request.urlopen(url))))
-
- # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- imagebox = OffsetImage(im, zoom = 0.35)
- ab = AnnotationBbox(imagebox, (0.125, 0.8), frameon = False)
- ax.add_artist(ab)
-
- if 'parentOrgId' in player_bio['people'][0]['currentTeam']:
- url = team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0]
-
- im = plt.imread(url)
- # response = requests.get(url)
- # im = Image.open(BytesIO(response.content))
- # im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0])
- # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- imagebox = OffsetImage(im, zoom = 0.25)
- ab = AnnotationBbox(imagebox, (0.875, 0.8), frameon = False)
- ax.add_artist(ab)
-
- else:
- url = team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['id']]['imageLink'].values[0]
- im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['id']]['imageLink'].values[0])
-
- # im = plt.imread(url)
- # response = requests.get(url)
- # im = Image.open(BytesIO(response.content))
- #im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0])
-
- # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- imagebox = OffsetImage(im, zoom = 0.25)
- ab = AnnotationBbox(imagebox, (0.875, 0.8), frameon = False)
- ax.add_artist(ab)
-
- ax.text(s = f'2023 {dict_level[sport_id_input]} Metrics',
-
- x = 0.5,
- y = 0.62,
- color='black',
- #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- fontsize = 20,
- ha='center',
- va='center')
-
- df_plot = df_summ_batter_pitch[column_list_pitch].xs([batter_select,df_summ_update.xs(batter_select,level=0).index[0]]).sort_values('pitches',ascending=False)#.dropna()
- df_plot = df_plot[df_plot['pitches'] > 0]
-
- df_plot_pct = df_summ_batter_pitch_pct[column_list_pitch].xs([batter_select,df_summ_update.xs(batter_select,level=0).index[0]]).sort_values('pitches',ascending=False)#.dropna()
-
- value = 1
- # Normalize the value
- colormap = plt.get_cmap(cmap_sum)
- colormap_r = plt.get_cmap(cmap_sum_r)
- norm = Normalize(vmin=0, vmax=1)
-
-
-
- col_5_colour = [colormap_r(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['chase_percent']))]
- col_4_colour = [colormap_r(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['whiff_rate']))]
- col_3_colour = [colormap(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['woba_percent_contact']))]
- col_2_colour = ['white']*len(df_summ_batter_pitch_pct_rank)
- col_1_colour = ['white']*len(df_summ_batter_pitch_pct_rank)
- colour_df = pd.DataFrame(data=[col_1_colour,col_2_colour,col_3_colour,col_4_colour,col_5_colour]).T.values
-
- ax_table = fig.add_subplot(gs[2, 1:-1])
- ax_table.axis('off')
- print(colour_df)
- print(df_plot)
- table = ax_table.table(cellText=df_plot.values, colLabels=[stat_plot_dict[x]['name'] for x in df_plot.columns],rowLabels=df_plot.index, cellLoc='center',
- bbox=[0.12, 0.0, 0.88, 1],colWidths=[0.03]+[0.03]*(len(df_plot.columns)),
- loc='center',cellColours=colour_df)
- ax_table.text(x=0.5,y=1.1,s='Metrics By Pitch Type',ha='center',fontdict={ 'size': 12},fontname='arial')
-
- w, h = table[0,1].get_width(), table[0,1].get_height()
- table.add_cell(0, -1, w,h, text='Pitch Type')
- min_font_size = 12
- # Set table properties
- table.auto_set_font_size(False)
- table.set_fontsize(min_font_size)
- #table.set_fontname('arial')
- table.scale(1, len(df_plot)*0.3)
-
-
- for n_col in range(0,len(df_plot.columns)):
- #print(df_plot.columns[n_col],f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}")
- format_col = df_plot[df_plot.columns[n_col]].astype(str)
- n_c = 0
- for cell in table.get_celld().values():
- # print([cell.get_text().get_text()],format_col.astype(str).values)
- if cell.get_text().get_text() in format_col.astype(str).values:
-
-
- #print(cell.get_text().get_text() in format_col.astype(str).values)
- cell.get_text().set_text(f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}".format(float(cell.get_text().get_text())))
- elif cell.get_text().get_text()[:-2] in format_col.astype(str).values:
- cell.get_text().set_text(f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}".format(float(cell.get_text().get_text())))
- n_c = n_c + 1
-
- stat_1 = input.stat_1()
- window_width_1 = input.window_1()
- stat_2 = input.stat_2()
- window_width_2 = input.window_2()
- stat_3 = input.stat_3()
- window_width_3 = input.window_3()
-
-
- inset_ax = ax = fig.add_subplot(gs[3, 1])
- rolling_plot(stat=stat_1,window_width=window_width_1,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- inset_ax = ax = fig.add_subplot(gs[3, 2])
- rolling_plot(stat=stat_2,window_width=window_width_2,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- inset_ax = ax = fig.add_subplot(gs[3, 3])
- rolling_plot(stat=stat_3,window_width=window_width_3,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- ax_bot = ax = fig.add_subplot(gs[4, :])
-
- ax_bot.text(x=0.05,y=-0.5,s='By: @TJStats',ha='left',fontdict={ 'size': 14},fontname='arial')
- ax_bot.text(x=1-0.05,y=-0.5,s='Data: MLB',ha='right',fontdict={ 'size': 14},fontname='arial')
- ax_bot.axis('off')
-
-
- ax_cbar = fig.add_subplot(gs[1,1:-1])
-
- cb = matplotlib.colorbar.ColorbarBase(ax_cbar, orientation='horizontal',
- cmap=cmap_sum)
- #ax_cbar.axis('off')
- ax_cbar.text(x=0.5,y=1.2,s='Colour Scale - Percentiles',ha='center',fontdict={ 'size': 12},fontname='arial')
- ax_cbar.text(s='0%',x=0.01,y=0.5,va='center',ha='left')
- ax_cbar.text(s='100%',x=0.99,y=0.5,va='center',ha='right')
- # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- ax_cbar.set_xticks([])
- ax_cbar.set_yticks([])
- ax_cbar.set_xticklabels([])
- ax_cbar.set_yticklabels([])
-
- # Display only the outline of the axis
- for spine in ax_cbar.spines.values():
- spine.set_visible(True) # Show only the outline
- spine.set_color('black') # Set the color to black
-
- # fig.set_facecolor('#ffffff')
-
- return fig.tight_layout()
-
-
-
- return plot_card(sport_id_input=sport_id_input,
- batter_select=batter_select,
- df_roll=df_roll,
- df_summ_player=df_summ_player,
- df_summ_batter_pitch_pct=df_summ_batter_pitch_pct,
- )
-
- # @render.plot(alt="LIDOM Plot")
- # def dom_plot():
- # ### Iniput data for the level
- # #time.sleep(2)
- # df_update = df_dom_update.copy()
- # df_summ_update = df_summ_dom_update.copy()
- # df_summ_avg_update = df_summ_avg_dom_update.copy()
- # if len(input.player_id()) < 1:
- # fig, ax = plt.subplots(1,1,figsize=(10,10))
- # ax.text(s='Please Select a Batter',x=0.5,y=0.5, ha='center')
- # ax.axis('off')
- # return fig
-
-
- # batter_select = int(input.player_id())
- # sport_id_input = 17
- # df_roll = df_update[df_update['batter_id']==batter_select]
- # if len(df_roll) == 0:
- # fig, ax = plt.subplots(1,1,figsize=(10,10))
- # ax.text(s='Card is Generating',x=0.5,y=0.5, ha='center')
- # ax.axis('off')
- # return fig
-
- # df_summ_filter = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[0]
- # df_summ_filter_pct = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[1]
- # df_summ_player = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[2]
- # df_summ_player_pct = df_summ_filter_out(df_summ=df_summ_update,batter_select = batter_select)[3]
-
- # df_summ_batter_pitch = df_summ_batter_pitch_up(df= df_update).set_index(['batter_id','batter_name','pitch_category'])
-
-
- # df_summ_batter_pitch_pct = df_summ_batter_pitch.loc[df_summ_filter.index.get_level_values(0)]
- # df_summ_batter_pitch_pct = df_summ_batter_pitch_pct[df_summ_batter_pitch_pct['pitches']>0]
- # df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct.groupby(level='pitch_category').apply(lambda x: x.rank(pct=True)).xs(batter_select,level=0)
-
- # df_summ_batter_pitch_pct_rank['pitch_count'] = df_summ_batter_pitch_pct_rank.index.get_level_values(1).map(df_summ_batter_pitch.xs(batter_select,level=0).reset_index().set_index('pitch_category')['pitches'].to_dict())
- # df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct_rank.sort_values('pitch_count',ascending=False)
- # #df_summ_batter_pitch_pct_rank = df_summ_batter_pitch_pct_rank.dropna()
- # def get_color(value, vmin, vmax, cmap_name=cmap_sum):
- # # Normalize the value within the range [0, 1]
- # normalized_value = (value - vmin) / (vmax - vmin)
-
- # # Get the colormap
- # cmap = plt.get_cmap(cmap_name)
-
- # # Map the normalized value to a color in the colormap
- # color = cmap(normalized_value)
-
- # # Convert the color from RGBA to hexadecimal format
- # hex_color = mcolors.rgb2hex(color)
-
- # return hex_color
-
- # def get_players(sport_id=1):
- # player_data = requests.get(url=f'https://statsapi.mlb.com/api/v1/sports/{sport_id}/players').json()
-
- # #Select relevant data that will help distinguish players from one another
- # fullName_list = [x['fullName'] for x in player_data['people']]
- # id_list = [x['id'] for x in player_data['people']]
- # position_list = [x['primaryPosition']['abbreviation'] for x in player_data['people']]
- # team_list = [x['currentTeam']['id']for x in player_data['people']]
- # age_list = [x['currentAge']for x in player_data['people']]
-
- # player_df = pd.DataFrame(data={'player_id':id_list,
- # 'name':fullName_list,
- # 'position':position_list,
- # 'team':team_list,
- # 'age':age_list})
- # return player_df
-
- # def get_teams():
- # teams = requests.get(url='https://statsapi.mlb.com/api/v1/teams/').json()
- # #Select only teams that are at the MLB level
- # # mlb_teams_city = [x['franchiseName'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # # mlb_teams_name = [x['teamName'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # # mlb_teams_franchise = [x['name'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # # mlb_teams_id = [x['id'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
- # # mlb_teams_abb = [x['abbreviation'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball']
-
- # mlb_teams_city = [x['franchiseName'] if 'franchiseName' in x else None for x in teams['teams']]
- # mlb_teams_name = [x['teamName'] if 'franchiseName' in x else None for x in teams['teams']]
- # mlb_teams_franchise = [x['name'] if 'franchiseName' in x else None for x in teams['teams']]
- # mlb_teams_id = [x['id'] if 'franchiseName' in x else None for x in teams['teams']]
- # mlb_teams_abb = [x['abbreviation'] if 'franchiseName' in x else None for x in teams['teams']]
- # mlb_teams_parent_id = [x['parentOrgId'] if 'parentOrgId' in x else None for x in teams['teams']]
- # mlb_teams_parent = [x['parentOrgName'] if 'parentOrgName' in x else None for x in teams['teams']]
- # mlb_teams_league_id = [x['league']['id'] if 'id' in x['league'] else None for x in teams['teams']]
- # mlb_teams_league_name = [x['league']['name'] if 'name' in x['league'] else None for x in teams['teams']]
-
-
-
- # #Create a dataframe of all the teams
- # mlb_teams_df = pd.DataFrame(data={'team_id':mlb_teams_id,
- # 'city':mlb_teams_franchise,
- # 'name':mlb_teams_name,
- # 'franchise':mlb_teams_franchise,
- # 'abbreviation':mlb_teams_abb,
- # 'parent_org_id':mlb_teams_parent_id,
- # 'parent_org':mlb_teams_parent,
- # 'league_id':mlb_teams_league_id,
- # 'league_name':mlb_teams_league_name
-
- # }).drop_duplicates().dropna(subset=['team_id']).reset_index(drop=True).sort_values('team_id')
-
- # mlb_teams_df.loc[mlb_teams_df['parent_org_id'].isnull(),'parent_org_id'] = mlb_teams_df.loc[mlb_teams_df['parent_org_id'].isnull(),'team_id']
- # mlb_teams_df.loc[mlb_teams_df['parent_org'].isnull(),'parent_org'] = mlb_teams_df.loc[mlb_teams_df['parent_org'].isnull(),'franchise']
-
-
- # mlb_teams_df['parent_org_abbreviation'] = mlb_teams_df['parent_org_id'].map(mlb_teams_df.set_index('team_id')['abbreviation'].to_dict())
-
- # mlb_teams_df = pd.concat([mlb_teams_df, pd.DataFrame({'team_id': 11,
- # 'city': 'Major League Baseball',
- # 'name': 'Major League Baseball',
- # 'franchise': 'Free Agent',
- # 'abbreviation': 'MLB',
- # 'parent_org_id': 11,
- # 'parent_org': 'Major League Baseball',
- # 'league_id': 1.0,
- # 'league_name': 'Major League Baseball',
- # 'parent_org_abbreviation': 'MLB'},index=[0])]).reset_index(drop=True)
-
- # #mlb_teams_df.loc[mlb_teams_df.franchise.isin(mlb_teams_df.parent_org.unique()),'parent_org'] = mlb_teams_df.loc[mlb_teams_df.franchise.isin(mlb_teams_df.parent_org.unique()),'franchise']
-
- # return mlb_teams_df
-
- # def rolling_plot(stat='k_percent',window_width=100,ax=0,df_r=df_roll,df_r_summ_avg=pd.DataFrame(),stat_plot_dict_rolling=stat_plot_dict_rolling):
- # plot = sns.lineplot(x=range(window_width,len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]>0])+1),
- # y=df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1].fillna(0).rolling(window=window_width)[stat_plot_dict_rolling[stat]['y']].sum().dropna()/window_width,
- # ax=ax,
- # color="#FFB000",
- # zorder=10)
-
-
- # print(df_r_summ_avg)
- # # ["#0C7BDC","#FFFFFF","#FFB000"])
- # ax.set_xlim(window_width,len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]))
- # ax.set_xlabel(stat_plot_dict_rolling[stat]['x_label'],fontsize=8)
- # ax.set_ylabel(stat_plot_dict_rolling[stat]['name'],fontsize=8)
-
- # ax.hlines(df_r_summ_avg[stat_plot_dict_rolling[stat]['y']]/df_r_summ_avg[stat_plot_dict_rolling[stat]['div']],
- # xmin=window_width,
- # xmax=len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]),
- # color="#0C7BDC",linestyles='-.')
- # ax.hlines(sum(df_r[stat_plot_dict_rolling[stat]['y']].dropna())/sum(df_r[stat_plot_dict_rolling[stat]['div']].dropna()),
- # xmin=window_width,
- # xmax=len(df_r[df_r[stat_plot_dict_rolling[stat]['div']]==1]),
- # color="#FFB000",linestyles='--')
- # #print(sum(df_r[stat_plot_dict_rolling[stat]['y']].dropna())/sum(df_r[stat_plot_dict_rolling[stat]['div']].dropna()))
- # ax.tick_params(axis='x', labelsize=8) # Set x-axis ticks size
- # ax.tick_params(axis='y', labelsize=8) # Set y-axis ticks size
- # ax.set_title(f"{window_width} {stat_plot_dict_rolling[stat]['x_label']} Rolling {stat_plot_dict_rolling[stat]['name']}",fontsize=8)
- # ax.set_ylim(stat_plot_dict_rolling[stat]['y_min'],stat_plot_dict_rolling[stat]['y_max'])
- # ax.grid(True,alpha=0.2)
-
-
- # if stat_plot_dict_rolling[stat]['form'] == '3f':
- # ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('{x:.3f}'))
-
- # elif stat_plot_dict_rolling[stat]['form'] == '1f':
- # ax.yaxis.set_major_formatter(mtick.StrMethodFormatter('{x:.1f}'))
-
- # elif stat_plot_dict_rolling[stat]['form'] == '1%':
- # ax.yaxis.set_major_formatter(mtick.PercentFormatter(1))
-
- # return plot
-
- # dict_level = {1:'MLB',
- # 11:'MiLB AAA',
- # 12:'MiLB AA',
- # 13:'MiLB High-A',
- # 14:'MiLB A',
- # 17:'Dominican Winter League'}
-
- # def plot_card(sport_id_input=sport_id_input,
- # batter_select=batter_select,
- # df_roll=df_roll,
- # df_summ_player=df_summ_player,
- # df_summ_update = df_summ_update,
- # df_summ_batter_pitch_pct=df_summ_batter_pitch_pct,
- # ):
-
- # #player_df = get_players(sport_id=sport_id_input)
- # mlb_teams = get_teams()
- # team_logos = pd.read_csv('team_logos.csv')
- # if sport_id_input == 1:
- # player_bio = requests.get(f'https://statsapi.mlb.com/api/v1/people?personIds={batter_select}&appContext=majorLeague&hydrate=currentTeam').json()
- # else:
- # player_bio = requests.get(f'https://statsapi.mlb.com/api/v1/people?personIds={batter_select}&appContext=minorLeague&hydrate=currentTeam').json()
-
- # fig = plt.figure(figsize=(10, 10))#,dpi=600)
- # plt.rcParams.update({'figure.autolayout': True})
- # fig.set_facecolor('white')
- # sns.set_theme(style="whitegrid", palette="pastel")
- # from matplotlib.gridspec import GridSpec
- # gs = GridSpec(5, 5, width_ratios=[0.2,1,1,1,0.2], height_ratios=[0.6,0.05,0.15,.30,0.025])
- # #gs.update(hspace=0, wspace=0)
-
- # # gs.update(left=0.1,right=0.9,top=0.97,bottom=0.03,wspace=0.3,hspace=0.09)
-
- # # ax1 = plt.subplot(4,1,1)
- # # ax2 = plt.subplot(2,2,2)
- # # ax3 = plt.subplot(2,2,3)
- # # ax4 = plt.subplot(4,1,4)
- # #ax2 = plt.subplot(3,3,2)
-
- # # Add subplots to the grid
- # ax = fig.add_subplot(gs[0, :])
- # #ax1 = fig.add_subplot(gs[2, 0])
- # # ax2 = fig.add_subplot(gs[2, :]) # Subplot at the top-right position
- # # fig, ax = plt.subplots(1,1,figsize=(10,12))
- # ax.axis('off')
-
- # width = 0.08
- # height = width*2.45
- # if df_summ_player['launch_speed'].isna().values[0]:
- # df_summ_player['sweet_spot_percent'] = np.nan
- # df_summ_player['barrel_percent'] = np.nan
- # df_summ_player['hard_hit_percent'] = np.nan
- # if df_summ_player['launch_speed'].isna().values[0]:
- # df_summ_player_pct['sweet_spot_percent'] = np.nan
- # df_summ_player_pct['barrel_percent'] = np.nan
- # df_summ_player_pct['hard_hit_percent'] = np.nan
- # # x = 0.1
- # # y = 0.9
- # for cat in range(len(column_list)):
-
- # # if cat < len(column_list)/2:
- # x_adjust, y_adjust =(0.85/7*8)*cat/8+0.075 - (0.85/7*8)*math.floor((cat)/8), 0.45-math.floor((cat)/8)/3.2
-
- # # else:
- # # x_adjust, y_adjust = (cat-len(column_list)/2)*(1.7/(math.ceil((len(column_list)-1))))+0.1, 0.5
- # #print( x_adjust, y_adjust)
- # if sum(df_summ_player[column_list[cat]].isna()) < 1:
- # print(f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}')
- # ax.text(s = f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}'.format().strip(),
-
- # x = x_adjust,
- # y = y_adjust,
- # color='black',
- # #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- # fontsize = 16,
- # ha='center',
- # va='center')
-
- # if stat_plot_dict[column_list[cat]]['flip']:
-
- # bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- # facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum_r))
- # ax.add_patch(bbox)
-
-
- # else:
- # bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- # facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum))
- # ax.add_patch(bbox)
- # else:
- # print(f'{df_summ_player[column_list[cat]].values[0]:{stat_plot_dict[column_list[cat]]["format"]}}')
- # ax.text(s = f'{df_summ_player[column_list[cat]].fillna("N/A").values[0]}',
-
- # x = x_adjust,
- # y = y_adjust,
- # color='black',
- # #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- # fontsize = 14,
- # ha='center',
- # va='center')
-
- # if stat_plot_dict[column_list[cat]]['flip']:
-
- # bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- # facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum_r))
- # ax.add_patch(bbox)
-
-
- # else:
- # bbox = patches.Rectangle((x_adjust- width/2,y_adjust- height/2), width, height, linewidth=1,edgecolor='black',
- # facecolor = get_color(df_summ_player_pct[column_list[cat]].values[0],0,1,cmap_name=cmap_sum))
- # ax.add_patch(bbox)
-
- # ax.text(s = stat_plot_dict[column_list[cat]]['name'],
-
- # x = x_adjust,
- # y = y_adjust-0.14,
- # color='black',
- # #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- # fontsize = 12,
- # ha='center',
- # va='center')
-
- # ax.text(s = f"{player_bio['people'][0]['fullName']}",
-
- # x = 0.5,
- # y = 0.95,
- # color='black',
- # #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- # fontsize = 28,
- # ha='center',
- # va='center')
- # if 'parentOrgId' in player_bio['people'][0]['currentTeam']:
-
- # ax.text(s = f"{player_bio['people'][0]['primaryPosition']['abbreviation']}, {mlb_teams[mlb_teams['team_id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['franchise'].values[0]}",
-
- # x = 0.5,
- # y = 0.85,
- # color='black',
- # #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- # fontsize = 14,
- # ha='center',
- # va='center')
-
- # else: ax.text(s = f"{player_bio['people'][0]['primaryPosition']['abbreviation']}, {player_bio['people'][0]['currentTeam']['name']}",
-
- # x = 0.5,
- # y = 0.85,
- # color='black',
- # #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- # fontsize = 14,
- # ha='center',
- # va='center')
-
- # ax.text(s =
- # f"B/T: {player_bio['people'][0]['batSide']['code']}/"
- # f"{player_bio['people'][0]['pitchHand']['code']} "
- # f"{player_bio['people'][0]['height']}/"
- # f"{player_bio['people'][0]['weight']}",
-
- # x = 0.5,
- # y = 0.785,
- # color='black',
- # #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- # fontsize = 14,
- # ha='center',
- # va='center')
-
- # ax.text(s =
-
- # f"DOB: {player_bio['people'][0]['birthDate']} "
- # f"Age: {player_bio['people'][0]['currentAge']}",
- # x = 0.5,
- # y = 0.72,
- # color='black',
- # #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- # fontsize = 14,
- # ha='center',
- # va='center')
- # if sport_id_input == 1:
- # try:
- # url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/{batter_select}/headshot/67/current.png'
- # test_mage = plt.imread(url)
- # except urllib.error.HTTPError as err:
- # url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/1/headshot/67/current.png'
-
- # else:
- # try:
- # url = f'https://img.mlbstatic.com/mlb-photos/image/upload/c_fill,g_auto/w_180/v1/people/{batter_select}/headshot/milb/current.png'
- # test_mage = plt.imread(url)
- # except urllib.error.HTTPError as err:
- # url = f'https://img.mlbstatic.com/mlb-photos/image/upload/d_people:generic:headshot:67:current.png/w_213,q_auto:best/v1/people/1/headshot/67/current.png'
- # im = plt.imread(url)
- # # response = requests.get(url)
- # # im = Image.open(BytesIO(response.content), cmap='viridis')
- # # im = plt.imread(np.array(PIL.Image.open(urllib.request.urlopen(url))))
-
- # # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- # imagebox = OffsetImage(im, zoom = 0.35)
- # ab = AnnotationBbox(imagebox, (0.125, 0.8), frameon = False)
- # ax.add_artist(ab)
-
- # if 'parentOrgId' in player_bio['people'][0]['currentTeam']:
- # url = team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0]
-
- # im = plt.imread(url)
- # # response = requests.get(url)
- # # im = Image.open(BytesIO(response.content))
- # # im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0])
- # # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- # imagebox = OffsetImage(im, zoom = 0.25)
- # ab = AnnotationBbox(imagebox, (0.875, 0.8), frameon = False)
- # ax.add_artist(ab)
-
- # else:
- # url = team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['id']]['imageLink'].values[0]
- # im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['id']]['imageLink'].values[0])
-
- # # im = plt.imread(url)
- # # response = requests.get(url)
- # # im = Image.open(BytesIO(response.content))
- # #im = plt.imread(team_logos[team_logos['id'] == player_bio['people'][0]['currentTeam']['parentOrgId']]['imageLink'].values[0])
-
- # # ax = fig.add_axes([0,0,1,0.85], anchor='C', zorder=1)
- # imagebox = OffsetImage(im, zoom = 0.25)
- # ab = AnnotationBbox(imagebox, (0.875, 0.8), frameon = False)
- # ax.add_artist(ab)
-
- # ax.text(s = f'2023 {dict_level[sport_id_input]} Metrics',
-
- # x = 0.5,
- # y = 0.62,
- # color='black',
- # #bbox=dict(facecolor='none', edgecolor='black', pad=10.0),
- # fontsize = 20,
- # ha='center',
- # va='center')
-
- # df_plot = df_summ_batter_pitch[column_list_pitch].xs([batter_select,df_summ_update.xs(batter_select,level=0).index[0]]).sort_values('pitches',ascending=False)#.dropna()
- # df_plot = df_plot[df_plot['pitches'] > 0]
-
- # df_plot_pct = df_summ_batter_pitch_pct[column_list_pitch].xs([batter_select,df_summ_update.xs(batter_select,level=0).index[0]]).sort_values('pitches',ascending=False)#.dropna()
-
- # value = 1
- # # Normalize the value
- # colormap = plt.get_cmap(cmap_sum)
- # colormap_r = plt.get_cmap(cmap_sum_r)
- # norm = Normalize(vmin=0, vmax=1)
-
-
-
- # col_5_colour = [colormap_r(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['chase_percent']))]
- # col_4_colour = [colormap_r(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['whiff_rate']))]
- # col_3_colour = [colormap(norm(x)) for x in list((df_summ_batter_pitch_pct_rank['woba_percent_contact']))]
- # col_2_colour = ['white']*len(df_summ_batter_pitch_pct_rank)
- # col_1_colour = ['white']*len(df_summ_batter_pitch_pct_rank)
- # colour_df = pd.DataFrame(data=[col_1_colour,col_2_colour,col_3_colour,col_4_colour,col_5_colour]).T.values
-
- # ax_table = fig.add_subplot(gs[2, 1:-1])
- # ax_table.axis('off')
- # print(colour_df)
- # print(df_plot)
- # table = ax_table.table(cellText=df_plot.values, colLabels=[stat_plot_dict[x]['name'] for x in df_plot.columns],rowLabels=df_plot.index, cellLoc='center',
- # bbox=[0.12, 0.0, 0.88, 1],colWidths=[0.03]+[0.03]*(len(df_plot.columns)),
- # loc='center',cellColours=colour_df)
- # ax_table.text(x=0.5,y=1.1,s='Metrics By Pitch Type',ha='center',fontdict={ 'size': 12},fontname='arial')
-
- # w, h = table[0,1].get_width(), table[0,1].get_height()
- # table.add_cell(0, -1, w,h, text='Pitch Type')
- # min_font_size = 12
- # # Set table properties
- # table.auto_set_font_size(False)
- # table.set_fontsize(min_font_size)
- # #table.set_fontname('arial')
- # table.scale(1, len(df_plot)*0.3)
-
-
- # for n_col in range(0,len(df_plot.columns)):
- # #print(df_plot.columns[n_col],f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}")
- # format_col = df_plot[df_plot.columns[n_col]].astype(str)
- # n_c = 0
- # for cell in table.get_celld().values():
- # # print([cell.get_text().get_text()],format_col.astype(str).values)
- # if cell.get_text().get_text() in format_col.astype(str).values:
-
-
- # #print(cell.get_text().get_text() in format_col.astype(str).values)
- # cell.get_text().set_text(f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}".format(float(cell.get_text().get_text())))
- # elif cell.get_text().get_text()[:-2] in format_col.astype(str).values:
- # cell.get_text().set_text(f"{{:{stat_plot_dict[df_plot.columns[n_col]]['format']}}}".format(float(cell.get_text().get_text())))
- # n_c = n_c + 1
-
- # stat_1 = input.stat_1()
- # window_width_1 = input.window_1()
- # stat_2 = input.stat_2()
- # window_width_2 = input.window_2()
- # stat_3 = input.stat_3()
- # window_width_3 = input.window_3()
-
-
- # inset_ax = ax = fig.add_subplot(gs[3, 1])
- # rolling_plot(stat=stat_1,window_width=window_width_1,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- # inset_ax = ax = fig.add_subplot(gs[3, 2])
- # rolling_plot(stat=stat_2,window_width=window_width_2,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- # inset_ax = ax = fig.add_subplot(gs[3, 3])
- # rolling_plot(stat=stat_3,window_width=window_width_3,ax=inset_ax,df_r=df_roll,df_r_summ_avg=df_summ_avg_update)
-
- # ax_bot = ax = fig.add_subplot(gs[4, :])
-
- # ax_bot.text(x=0.05,y=-0.5,s='By: @TJStats',ha='left',fontdict={ 'size': 14},fontname='arial')
- # ax_bot.text(x=1-0.05,y=-0.5,s='Data: MLB',ha='right',fontdict={ 'size': 14},fontname='arial')
- # ax_bot.axis('off')
-
-
- # ax_cbar = fig.add_subplot(gs[1,1:-1])
-
- # cb = matplotlib.colorbar.ColorbarBase(ax_cbar, orientation='horizontal',
- # cmap=cmap_sum)
- # #ax_cbar.axis('off')
- # ax_cbar.text(x=0.5,y=1.2,s='Colour Scale - Percentiles',ha='center',fontdict={ 'size': 12},fontname='arial')
- # ax_cbar.text(s='0%',x=0.01,y=0.5,va='center',ha='left')
- # ax_cbar.text(s='100%',x=0.99,y=0.5,va='center',ha='right')
- # # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- # # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- # # ax_cbar.text(s='50%',x=0.5,y=0.5,va='center',ha='center')
- # ax_cbar.set_xticks([])
- # ax_cbar.set_yticks([])
- # ax_cbar.set_xticklabels([])
- # ax_cbar.set_yticklabels([])
-
- # # Display only the outline of the axis
- # for spine in ax_cbar.spines.values():
- # spine.set_visible(True) # Show only the outline
- # spine.set_color('black') # Set the color to black
-
- # # fig.set_facecolor('#ffffff')
-
- # return fig.tight_layout()
-
-
-
- # return plot_card(sport_id_input=sport_id_input,
- # batter_select=batter_select,
- # df_roll=df_roll,
- # df_summ_player=df_summ_player,
- # df_summ_batter_pitch_pct=df_summ_batter_pitch_pct,
- # )
-
-
-from shiny import App, Inputs, Outputs, Session, reactive, render, req, ui
-
-
-
-app = App(ui.page_fluid(
-# ui.tags.base(href=base_url),
- ui.tags.div(
- {"style": "width:90%;margin: 0 auto;max-width: 1600px;"},
- ui.tags.style(
- """
- h4 {
- margin-top: 1em;font-size:35px;
- }
- h2{
- font-size:25px;
- }
- """
- ),
- shinyswatch.theme.simplex(),
- ui.tags.h4("TJStats"),
- ui.tags.i("Baseball Analytics and Visualizations"),
- ui.markdown("""Support me on Patreon for Access to 2024 Apps1"""),
-
- ui.navset_tab(
- ui.nav_control(
- ui.a(
- "Home",
- href="https://nesticot-tjstats-site.hf.space/home/"
- ),
- ),
- ui.nav_menu(
- "Batter Charts",
- ui.nav_control(
- ui.a(
- "Batting Rolling",
- href="https://nesticot-tjstats-site-rolling-batter.hf.space/"
- ),
- ui.a(
- "Spray",
- href="https://nesticot-tjstats-site-spray.hf.space/"
- ),
- ui.a(
- "Decision Value",
- href="https://nesticot-tjstats-site-decision-value.hf.space/"
- ),
- ui.a(
- "Damage Model",
- href="https://nesticot-tjstats-site-damage.hf.space/"
- ),
- ui.a(
- "Batter Scatter",
- href="https://nesticot-tjstats-site-batter-scatter.hf.space/"
- ),
- ui.a(
- "EV vs LA Plot",
- href="https://nesticot-tjstats-site-ev-angle.hf.space/"
- ),
- ui.a(
- "Statcast Compare",
- href="https://nesticot-tjstats-site-statcast-compare.hf.space/"
- ),
- ui.a(
- "MLB/MiLB Cards",
- href="https://nesticot-tjstats-site-mlb-cards.hf.space/"
- )
- ),
- ),
- ui.nav_menu(
- "Pitcher Charts",
- ui.nav_control(
- ui.a(
- "Pitcher Rolling",
- href="https://nesticot-tjstats-site-rolling-pitcher.hf.space/"
- ),
- ui.a(
- "Pitcher Summary",
- href="https://nesticot-tjstats-site-pitching-summary-graphic-new.hf.space/"
- ),
- ui.a(
- "Pitcher Scatter",
- href="https://nesticot-tjstats-site-pitcher-scatter.hf.space"
- )
- ),
- )), ui.row(
- ui.layout_sidebar(
-
- ui.panel_sidebar(ui.output_ui('test',"Select Batter"),
- ui.input_select('stat_1',"Select Rolling Stat 1",stat_roll_dict,selectize=True),
- ui.input_numeric('window_1',"Select Rolling Window 1",value=100),
- ui.input_select('stat_2',"Select Rolling Stat 2",stat_roll_dict,selected='k_percent',selectize=True),
- ui.input_numeric('window_2',"Select Rolling Stat 2",value=100),
- ui.input_select('stat_3',"Select Rolling Stat 3",stat_roll_dict,selected='bb_percent',selectize=True),
- ui.input_numeric('window_3',"Select Rolling Stat 3",value=100),
- ui.input_action_button("go", "Generate",class_="btn-primary"),width=2),
-
- ui.page_navbar(
-
- ui.nav_panel("MLB",
- ui.output_plot('mlb_plot',width='1000px',height='1000px')),
- ui.nav_panel("AAA",
- ui.output_plot('aaa_plot',width='1000px',height='1000px')),
- ui.nav_panel("AA",
- ui.output_plot('aa_plot',width='1000px',height='1000px')),
- ui.nav_panel("High-A",
- ui.output_plot('ha_plot',width='1000px',height='1000px')),
- ui.nav_panel("A",
- ui.output_plot('a_plot',width='1000px',height='1000px')),
- id="my_tabs",
- ))),)),server)
-
-
-
-# app = App(app_ui, server)