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)