from shiny import App, Inputs, Outputs, Session, reactive, render, req, ui
import datasets
from datasets import load_dataset
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from scipy.stats import gaussian_kde
import matplotlib
from matplotlib.ticker import MaxNLocator
from matplotlib.gridspec import GridSpec
from scipy.stats import zscore
import math
import matplotlib
from adjustText import adjust_text
import matplotlib.ticker as mtick
from shinywidgets import output_widget, render_widget
import pandas as pd
#from configure import base_url
import shinyswatch
import inflect
from matplotlib.pyplot import text
import rolling_pitcher_functions as rpf
def percentile(n):
def percentile_(x):
return np.nanpercentile(x, n)
percentile_.__name__ = 'percentile_%s' % n
return percentile_
colour_palette = ['#FFB000','#648FFF','#785EF0',
'#DC267F','#FE6100','#3D1EB2','#894D80','#16AA02','#B5592B','#A3C1ED']
print('Starting Everything:')
# exit_velo_df = milb_a_ev_df.append([triple_a_ev_df,double_a_ev_df,a_high_a_ev_df,single_a_ev_df]).reset_index(drop=True)
# player_df_all = mlb_a_player_df.append([triple_a_player_df,double_a_player_df,a_high_a_player_df,single_a_player_df]).reset_index(drop=True)
# exit_velo_df = pd.read_csv('exit_velo_df_all.csv',index_col=[0])
# player_df_all = pd.read_csv('player_df_all.csv',index_col=[0])
# pa_df = pd.read_csv('pa_df_all.csv',index_col=[0])
# pa_df_full_na = pa_df.dropna()
### Import Datasets
dataset = load_dataset('nesticot/mlb_data', data_files=['mlb_pitch_data_2024.csv',
])
dataset_train = dataset['train']
exit_velo_df_mlb = dataset_train.to_pandas().set_index(list(dataset_train.features.keys())[0]).reset_index(drop=True)
#print(df_2023)
exit_velo_df_mlb['level'] = 'MLB'
### Import Datasets
dataset = load_dataset('nesticot/mlb_data', data_files=['aaa_pitch_data_2024.csv',
])
dataset_train = dataset['train']
exit_velo_df_aaa = dataset_train.to_pandas().set_index(list(dataset_train.features.keys())[0]).reset_index(drop=True)
#print(df_2023)
exit_velo_df_aaa['level'] = 'AAA'
### Import Datasets
dataset = load_dataset('nesticot/mlb_data', data_files=['aa_pitch_data_2024.csv',
])
dataset_train = dataset['train']
exit_velo_df_aa = dataset_train.to_pandas().set_index(list(dataset_train.features.keys())[0]).reset_index(drop=True)
#print(df_2023)
exit_velo_df_aa['level'] = 'AA'
### Import Datasets
dataset = load_dataset('nesticot/mlb_data', data_files=['high_a_pitch_data_2024.csv',
])
dataset_train = dataset['train']
exit_velo_df_ha = dataset_train.to_pandas().set_index(list(dataset_train.features.keys())[0]).reset_index(drop=True)
#print(df_2023)
exit_velo_df_ha['level'] = 'A+'
### Import Datasets
dataset = load_dataset('nesticot/mlb_data', data_files=['a_pitch_data_2024.csv',
])
dataset_train = dataset['train']
exit_velo_df_a = dataset_train.to_pandas().set_index(list(dataset_train.features.keys())[0]).reset_index(drop=True)
#print(df_2023)
exit_velo_df_a['level'] = 'A'
exit_velo_df = pd.concat([exit_velo_df_mlb,exit_velo_df_aaa,exit_velo_df_aa,exit_velo_df_ha,exit_velo_df_a])
# exit_velo_df_copy = exit_velo_df.copy()
# exit_velo_df = exit_velo_df_copy.copy()
end_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', 'intent_walk',
'fielders_choice_out', 'strikeout_double_play',
'sac_fly_double_play', 'catcher_interf', 'other_out']
exit_velo_df['pa'] = exit_velo_df.event_type.isin(end_codes)
#exit_velo_df['pa'] = 1
exit_velo_df['k'] = exit_velo_df.event_type.isin(list(filter(None, [x if 'strikeout' in x else '' for x in exit_velo_df.event_type.fillna('None').unique()])))
exit_velo_df['bb'] = exit_velo_df.event_type.isin(list(filter(None, [x if 'walk' in x else '' for x in exit_velo_df.event_type.fillna('None').unique()])))
exit_velo_df['k_minus_bb'] = exit_velo_df['k'].astype(np.float32)-exit_velo_df['bb'].astype(np.float32)
exit_velo_df = exit_velo_df.drop_duplicates(subset=['play_id'])
swing_codes = ['Swinging Strike', 'In play, no out',
'Foul', 'In play, out(s)',
'In play, run(s)', 'Swinging Strike (Blocked)',
'Foul Bunt','Foul Tip', 'Missed Bunt','Foul Pitchout','Swinging Pitchout']
swings_in = ['Swinging Strike', 'In play, no out',
'Foul', 'In play, out(s)',
'In play, run(s)', 'Swinging Strike (Blocked)',
'Foul Bunt','Foul Tip', 'Missed Bunt','Foul Pitchout','Swinging Pitchout']
swing_strike_codes = ['Swinging Strike',
'Swinging Strike (Blocked)','Missed Bunt','Foul Tip','Swinging Pitchout']
contact_codes = ['In play, no out',
'Foul', 'In play, out(s)',
'In play, run(s)',
'Foul Bunt']
codes_in = ['In play, out(s)',
'Swinging Strike',
'Ball',
'Foul',
'In play, no out',
'Called Strike',
'Foul Tip',
'In play, run(s)',
'Hit By Pitch',
'Ball In Dirt',
'Pitchout',
'Swinging Strike (Blocked)',
'Foul Bunt',
'Missed Bunt',
'Foul Pitchout',
'Intent Ball',
'Swinging Pitchout']
exit_velo_df['in_zone'] = exit_velo_df['zone'] < 10
exit_velo_df = exit_velo_df.drop_duplicates(subset=['play_id'])
exit_velo_df_codes = exit_velo_df[exit_velo_df.play_description.isin(codes_in)].dropna(subset=['in_zone'])
exit_velo_df_codes['bip'] = ~exit_velo_df_codes.launch_speed.isna()
conditions = [
(exit_velo_df_codes['launch_speed'].isna()),
(exit_velo_df_codes['launch_speed']*1.5 - exit_velo_df_codes['launch_angle'] >= 117 ) & (exit_velo_df_codes['launch_speed'] + exit_velo_df_codes['launch_angle'] >= 124) & (exit_velo_df_codes['launch_speed'] > 98) & (exit_velo_df_codes['launch_angle'] >= 8) & (exit_velo_df_codes['launch_angle'] <= 50)
]
choices = [False,True]
exit_velo_df_codes['barrel'] = np.select(conditions, choices, default=np.nan)
conditions_ss = [
(exit_velo_df_codes['launch_angle'].isna()),
(exit_velo_df_codes['launch_angle'] >= 8 ) * (exit_velo_df_codes['launch_angle'] <= 32 )
]
choices_ss = [False,True]
exit_velo_df_codes['sweet_spot'] = np.select(conditions_ss, choices_ss, default=np.nan)
conditions_hh = [
(exit_velo_df_codes['launch_speed'].isna()),
(exit_velo_df_codes['launch_speed'] >= 94.5 )
]
choices_hh = [False,True]
exit_velo_df_codes['hard_hit'] = np.select(conditions_hh, choices_hh, default=np.nan)
conditions_tb = [
(exit_velo_df_codes['event_type']=='single'),
(exit_velo_df_codes['event_type']=='double'),
(exit_velo_df_codes['event_type']=='triple'),
(exit_velo_df_codes['event_type']=='home_run'),
]
choices_tb = [1,2,3,4]
exit_velo_df_codes['tb'] = np.select(conditions_tb, choices_tb, default=np.nan)
conditions_woba = [
(exit_velo_df_codes['event_type']=='walk'),
(exit_velo_df_codes['event_type']=='hit_by_pitch'),
(exit_velo_df_codes['event_type']=='single'),
(exit_velo_df_codes['event_type']=='double'),
(exit_velo_df_codes['event_type']=='triple'),
(exit_velo_df_codes['event_type']=='home_run'),
]
choices_woba = [0.705,
0.688,
0.897,
1.233,
1.612,
2.013]
exit_velo_df_codes['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 = [
(exit_velo_df_codes['event_type'].isin(woba_codes))
]
choices_woba_code = [1]
exit_velo_df_codes['woba_codes'] = np.select(conditions_woba_code, choices_woba_code, default=np.nan)
#exit_velo_df_codes['barrel'] = (exit_velo_df_codes.launch_speed >= 98) & (exit_velo_df_codes.launch_angle >= (26 - (-98 + exit_velo_df_codes.launch_speed))) & (exit_velo_df_codes.launch_angle <= 30 + (-98 + exit_velo_df_codes.launch_speed)) & (exit_velo_df_codes.launch_angle >= 8) & (exit_velo_df_codes.launch_angle <= 50)
#exit_velo_df_codes['barrel'] = (exit_velo_df_codes.launch_speed >= 98) & (exit_velo_df_codes.launch_angle >= (26 - (-98 + exit_velo_df_codes.launch_speed))) & (exit_velo_df_codes.launch_angle <= 30 + (-98 + exit_velo_df_codes.launch_speed)) & (exit_velo_df_codes.launch_angle >= 8) & (exit_velo_df_codes.launch_angle <= 50)
exit_velo_df_codes['pitches'] = 1
exit_velo_df_codes['whiffs'] = [1 if ((x == 'S')|(x == 'W')|(x =='T')) else 0 for x in exit_velo_df_codes.play_code]
exit_velo_df_codes['csw'] = [1 if ((x == 'S')|(x == 'W')|(x =='T')|(x == 'C')) else 0 for x in exit_velo_df_codes.play_code]
exit_velo_df_codes['swings'] = [1 if x in swings_in else 0 for x in exit_velo_df_codes.play_description]
exit_velo_df_codes['out_zone'] = exit_velo_df_codes.in_zone == False
exit_velo_df_codes['zone_swing'] = (exit_velo_df_codes.in_zone == True)&(exit_velo_df_codes.swings == 1)
exit_velo_df_codes['zone_contact'] = (exit_velo_df_codes.in_zone == True)&(exit_velo_df_codes.swings == 1)&(exit_velo_df_codes.whiffs == 0)
exit_velo_df_codes['ozone_swing'] = (exit_velo_df_codes.in_zone==False)&(exit_velo_df_codes.swings == 1)
exit_velo_df_codes['ozone_contact'] = (exit_velo_df_codes.in_zone==False)&(exit_velo_df_codes.swings == 1)&(exit_velo_df_codes.whiffs == 0)
exit_velo_df_codes_summ = exit_velo_df_codes.groupby(['pitcher_id','pitcher_name','level']).agg(
pa = ('pa','sum'),
k = ('k','sum'),
bb = ('bb','sum'),
k_minus_bb = ('k_minus_bb','sum'),
csw = ('csw','sum'),
bip = ('bip','sum'),
tb = ('tb','sum'),
woba = ('woba','sum'),
woba_codes = ('woba_codes','sum'),
hard_hit = ('hard_hit','sum'),
barrel = ('barrel','sum'),
sweet_spot = ('sweet_spot','sum'),
max_launch_speed = ('launch_speed','max'),
launch_speed_90 = ('launch_speed',percentile(90)),
launch_speed = ('launch_speed','mean'),
launch_angle = ('launch_angle','mean'),
pitches = ('pitches','sum'),
swings = ('swings','sum'),
in_zone = ('in_zone','sum'),
out_zone = ('out_zone','sum'),
whiffs = ('whiffs','sum'),
zone_swing = ('zone_swing','sum'),
zone_contact = ('zone_contact','sum'),
ozone_swing = ('ozone_swing','sum'),
ozone_contact = ('ozone_contact','sum'),
).reset_index()
exit_velo_df_codes_summ['k_percent'] = [exit_velo_df_codes_summ.k[x]/exit_velo_df_codes_summ.pa[x] if exit_velo_df_codes_summ.pa[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ))]
exit_velo_df_codes_summ['bb_percent'] =[exit_velo_df_codes_summ.bb[x]/exit_velo_df_codes_summ.pa[x] if exit_velo_df_codes_summ.pa[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ))]
exit_velo_df_codes_summ['k_minus_bb_percent'] =[exit_velo_df_codes_summ.k_minus_bb[x]/exit_velo_df_codes_summ.pa[x] if exit_velo_df_codes_summ.pa[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ))]
exit_velo_df_codes_summ['sweet_spot_percent'] = [exit_velo_df_codes_summ.sweet_spot[x]/exit_velo_df_codes_summ.bip[x] if exit_velo_df_codes_summ.bip[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ))]
exit_velo_df_codes_summ['woba_percent'] = [exit_velo_df_codes_summ.woba[x]/exit_velo_df_codes_summ.woba_codes[x] if exit_velo_df_codes_summ.woba_codes[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ))]
exit_velo_df_codes_summ['hard_hit_percent'] = [exit_velo_df_codes_summ.hard_hit[x]/exit_velo_df_codes_summ.bip[x] if exit_velo_df_codes_summ.bip[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ))]
exit_velo_df_codes_summ['csw_percent'] = [exit_velo_df_codes_summ.csw[x]/exit_velo_df_codes_summ.pitches[x] if exit_velo_df_codes_summ.pitches[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ))]
exit_velo_df_codes_summ['barrel_percent'] = exit_velo_df_codes_summ.barrel = [exit_velo_df_codes_summ.barrel[x]/exit_velo_df_codes_summ.bip[x] if exit_velo_df_codes_summ.bip[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ))]
exit_velo_df_codes_summ['zone_contact_percent'] = [exit_velo_df_codes_summ.zone_contact[x]/exit_velo_df_codes_summ.zone_swing[x] if exit_velo_df_codes_summ.zone_swing[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ))]
exit_velo_df_codes_summ['zone_swing_percent'] = [exit_velo_df_codes_summ.zone_swing[x]/exit_velo_df_codes_summ.in_zone[x] if exit_velo_df_codes_summ.pitches[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ))]
exit_velo_df_codes_summ['zone_percent'] = [exit_velo_df_codes_summ.in_zone[x]/exit_velo_df_codes_summ.pitches[x] if exit_velo_df_codes_summ.pitches[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ))]
exit_velo_df_codes_summ['chase_percent'] = [exit_velo_df_codes_summ.ozone_swing[x]/(exit_velo_df_codes_summ.pitches[x] - exit_velo_df_codes_summ.in_zone[x]) if (exit_velo_df_codes_summ.pitches[x]- exit_velo_df_codes_summ.in_zone[x]) != 0 else np.nan for x in range(len(exit_velo_df_codes_summ))]
exit_velo_df_codes_summ['chase_contact'] = [exit_velo_df_codes_summ.ozone_contact[x]/exit_velo_df_codes_summ.ozone_swing[x] if exit_velo_df_codes_summ.ozone_swing[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ))]
exit_velo_df_codes_summ['swing_percent'] = [exit_velo_df_codes_summ.swings[x]/exit_velo_df_codes_summ.pitches[x] if exit_velo_df_codes_summ.pitches[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ))]
exit_velo_df_codes_summ['whiff_rate'] = [exit_velo_df_codes_summ.whiffs[x]/exit_velo_df_codes_summ.swings[x] if exit_velo_df_codes_summ.swings[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ))]
exit_velo_df_codes_summ['swstr_rate'] = [exit_velo_df_codes_summ.whiffs[x]/exit_velo_df_codes_summ.pitches[x] if exit_velo_df_codes_summ.pitches[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ))]
exit_velo_df_codes_summ = exit_velo_df_codes_summ.dropna(subset=['bip'])
print('whiffing')
print(exit_velo_df_codes_summ['whiff_rate'])
exit_velo_df_codes_summ.head()
woba_list = ['woba']
pa_list = ['k','bb','k_minus_bb','bb_minus_k']
balls_in_play_list = ['hard_hit','launch_speed','launch_speed_90','launch_angle','barrel','sweet_spot']
pitches_list = ['zone_percent','swing_percent','sw_str','csw']
swings_list = ['whiff_percent']
in_zone_pitches_list = ['zone_swing']
in_zone_swings_list = ['zone_contact']
out_zone_pitches_list = ['chase_percent']
out_zone_swings_list = ['chase_contact']
plot_dict = {
'k':{'x_axis':'Plate Appearances','y_axis':'K%','title':'K%','x_value':'k','x_range':[0.0,0.1,0.2,0.3,0.4],'percent':True,'percentile_label':'k_percent','flip_p':False,'percentile':False},
'bb':{'x_axis':'Plate Appearances','y_axis':'BB%','title':'BB%','x_value':'bb','x_range':[0.0,0.1,0.2,0.3],'percent':True,'percentile_label':'bb_percent','flip_p':True,'percentile':False},
'k_minus_bb':{'x_axis':'Plate Appearances','y_axis':'K-BB%','title':'K-BB%','x_value':'k_minus_bb','x_range':[-0.1,0,0.1,0.2,0.3,0.4,0.5],'percent':True,'percentile_label':'k_minus_bb_percent','flip_p':False,'percentile':False,'avg_adjust':False},
'csw':{'x_axis':'Pitches','y_axis':'CSW%','title':'CSW%','x_value':'csw','x_range':[.2,.25,.3,.35,.4],'percent':True,'percentile_label':'csw_percent','flip_p':False,'percentile':False},
'woba':{'x_axis':'wOBA PA','y_axis':'wOBA','title':'wOBA','x_value':'woba','x_range':[.20,.30,.40,.50],'percent':False,'percentile_label':'woba_percent','flip_p':True,'percentile':False,'avg_adjust':True},
'launch_speed':{'x_axis':'Balls In Play','y_axis':'Exit Velocity','title':'Exit Velocity','x_value':'launch_speed','x_range':[85,90,95,100,105],'percent':False,'percentile_label':'launch_speed','flip_p':True,'percentile':False},
'launch_speed_90':{'x_axis':'Balls In Play','y_axis':'90th Percentile Exit Velocity','title':'90th Percentile Exit Velocity','x_value':'launch_speed','x_range':[90,95,100,105,110,115,120],'percent':False,'percentile_label':'launch_speed_90','flip_p':True,'percentile':True},
'sweet_spot':{'x_axis':'Balls In Play','y_axis':'SweetSpot%','title':'SweetSpot%','x_value':'sweet_spot','x_range':[0.2,0.3,0.4,0.5,0.6],'percent':True,'percentile_label':'sweet_spot_percent','flip_p':True,'percentile':False},
'launch_angle':{'x_axis':'Balls In Play','y_axis':'Launch Angle','title':'Launch Angle','x_value':'launch_angle','x_range':[-20,-10,0,10,20],'percent':False,'percentile_label':'launch_angle','flip_p':True,'percentile':False},
'barrel':{'x_axis':'Balls In Play','y_axis':'Barrel%','title':'Barrel%','x_value':'barrel','x_range':[0,0.05,0.10,.15,.20,.25,.30],'percent':True,'percentile_label':'barrel_percent','flip_p':True,'percentile':False},
'zone_percent':{'x_axis':'Pitches','y_axis':'Zone%','title':'Zone%','x_value':'in_zone','x_range':[0.3,0.4,0.5,0.6,0.7],'percent':True,'percentile_label':'zone_percent','flip_p':False,'percentile':False},
'swing_percent':{'x_axis':'Pitches','y_axis':'Swing%','title':'Swing%','x_value':'swings','x_range':[0.2,0.3,0.4,0.5,0.6,0.7,0.8],'percent':True,'percentile_label':'swing_percent','flip_p':False,'percentile':False},
'whiff_percent':{'x_axis':'Swings','y_axis':'Whiff%','title':'Whiff%','x_value':'whiffs','x_range':[0.0,0.1,0.2,0.3,0.4,0.5],'percent':True,'percentile_label':'whiff_rate','flip_p':False,'percentile':False},
'sw_str':{'x_axis':'Pitches','y_axis':'SwStr%','title':'SwStr%','x_value':'whiffs','x_range':[0.0,0.05,0.1,0.15,0.2,0.25],'percent':True,'percentile_label':'swstr_rate','flip_p':False,'percentile':False},
'zone_swing':{'x_axis':'In-Zone Pitches','y_axis':'Z-Swing%','title':'Z-Swing%','x_value':'zone_swing','x_range':[0.3,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],'percent':True,'percentile_label':'zone_swing_percent','flip_p':True,'percentile':False},
'zone_contact':{'x_axis':'In-Zone Swings','y_axis':'Z-Contact%','title':'Z-Contact%','x_value':'zone_contact','x_range':[0.5,0.6,0.7,0.8,0.9,1],'percent':True,'percentile_label':'zone_contact_percent','flip_p':True,'percentile':False},
'chase_percent':{'x_axis':'Out-of-Zone Pitches','y_axis':'O-Swing%','title':'O-Swing%','x_value':'ozone_swing','x_range':[0.0,0.1,0.2,0.3,0.4,0.5],'percent':True,'percentile_label':'chase_percent','flip_p':False,'percentile':False},
'chase_contact':{'x_axis':'Out-of-Zone Swings','y_axis':'O-Contact%','title':'O-Contact%','x_value':'ozone_contact','x_range':[0.2,0.3,0.4,0.5,0.6,0.7,0.8],'percent':True,'percentile_label':'chase_contact','flip_p':True,'percentile':False},}
test_df = exit_velo_df.sort_values(by='pitcher_name').drop_duplicates(subset='pitcher_id').reset_index(drop=True)[['pitcher_id','pitcher_name']]#['pitcher'].to_dict()
test_df = test_df.set_index('pitcher_id')
#test_df = test_df[test_df.pitcher == 'Chris Bassitt'].append(test_df[test_df.pitcher != 'Chris Bassitt'])
#batter_dict = test_df['pitcher_name'].to_dict()
batter_dict_mlb = exit_velo_df_mlb.sort_values(['pitcher_name']).set_index('pitcher_id')['pitcher_name'].to_dict()
batter_dict_aaa = exit_velo_df_aaa.sort_values(['pitcher_name']).set_index('pitcher_id')['pitcher_name'].to_dict()
batter_dict_aa = exit_velo_df_aa.sort_values(['pitcher_name']).set_index('pitcher_id')['pitcher_name'].to_dict()
batter_dict_ha = exit_velo_df_ha.sort_values(['pitcher_name']).set_index('pitcher_id')['pitcher_name'].to_dict()
batter_dict_a = exit_velo_df_a.sort_values(['pitcher_name']).set_index('pitcher_id')['pitcher_name'].to_dict()
level_dict = {'MLB':'MLB','AAA':'AAA','AA':'AA','A+':'A+','A':'A'}
plot_dict_small = {
'k':'K%',
'bb':'BB%',
'k_minus_bb':'K-BB%',
'csw':'CSW%',
'woba':'wOBA',
'launch_speed':'Exit Velocity',
'launch_speed_90':'90th Percentile Exit Velocity',
'sweet_spot':'SweetSpot%',
'launch_angle':'Launch Angle',
'zone_percent':'Zone%',
'barrel':'Barrel%',
'swing_percent':'Swing%',
'whiff_percent':'Whiff%',
'sw_str':'SwStr%',
'zone_swing':'Z-Swing%',
'zone_contact':'Z-Contact%',
'chase_percent':'O-Swing%',
'chase_contact':'O-Contact%',}
def server(input,output,session):
@render.ui
def test():
# @reactive.Effect
if input.my_tabs() == 'MLB':
#test_df = test_df[test_df.pitcher == 'Chris Bassitt'].append(test_df[test_df.pitcher != 'Chris Bassitt'])
#batter_dict = exit_velo_df_mlb.set_index('batter_id')['batter_name'].to_dict()
return ui.input_select("id", "Select Player",batter_dict_mlb,selectize=True)
if input.my_tabs() == 'AAA':
#test_df = test_df[test_df.pitcher == 'Chris Bassitt'].append(test_df[test_df.pitcher != 'Chris Bassitt'])
#batter_dict = exit_velo_df_aaa.set_index('batter_id')['batter_name'].to_dict()
return ui.input_select("id", "Select Player",batter_dict_aaa,selectize=True)
if input.my_tabs() == 'AA':
#test_df = test_df[test_df.pitcher == 'Chris Bassitt'].append(test_df[test_df.pitcher != 'Chris Bassitt'])
#batter_dict = exit_velo_df_aaa.set_index('batter_id')['batter_name'].to_dict()
return ui.input_select("id", "Select Player",batter_dict_aa,selectize=True)
if input.my_tabs() == 'A+':
#test_df = test_df[test_df.pitcher == 'Chris Bassitt'].append(test_df[test_df.pitcher != 'Chris Bassitt'])
#batter_dict = exit_velo_df_aaa.set_index('batter_id')['batter_name'].to_dict()
return ui.input_select("id", "Select Player",batter_dict_ha,selectize=True)
if input.my_tabs() == 'A':
#test_df = test_df[test_df.pitcher == 'Chris Bassitt'].append(test_df[test_df.pitcher != 'Chris Bassitt'])
#batter_dict = exit_velo_df_aaa.set_index('batter_id')['batter_name'].to_dict()
return ui.input_select("id", "Select Player",batter_dict_a,selectize=True)
@output
@render.plot(alt="A histogram")
@reactive.event(input.go, ignore_none=False)
def plot_mlb():
rpf.rolling_plot(df = exit_velo_df_codes[exit_velo_df_codes['level']==input.my_tabs()],
df_summ = exit_velo_df_codes_summ[exit_velo_df_codes_summ['level']==input.my_tabs()],
player_id = input.id(),
stat_id = input.stat_id(),
batter_dict = batter_dict_mlb,
window_select = input.n(),
level_id = input.my_tabs())
@output
@render.plot(alt="A histogram")
@reactive.event(input.go, ignore_none=False)
def plot_aaa():
rpf.rolling_plot(df = exit_velo_df_codes[exit_velo_df_codes['level']==input.my_tabs()],
df_summ = exit_velo_df_codes_summ[exit_velo_df_codes_summ['level']==input.my_tabs()],
player_id = input.id(),
stat_id = input.stat_id(),
batter_dict = batter_dict_aaa,
window_select = input.n(),
level_id = input.my_tabs())
@output
@render.plot(alt="A histogram")
@reactive.event(input.go, ignore_none=False)
def plot_aa():
rpf.rolling_plot(df = exit_velo_df_codes[exit_velo_df_codes['level']==input.my_tabs()],
df_summ = exit_velo_df_codes_summ[exit_velo_df_codes_summ['level']==input.my_tabs()],
player_id = input.id(),
stat_id = input.stat_id(),
batter_dict = batter_dict_aa,
window_select = input.n(),
level_id = input.my_tabs())
@output
@render.plot(alt="A histogram")
@reactive.event(input.go, ignore_none=False)
def plot_ha():
rpf.rolling_plot(df = exit_velo_df_codes[exit_velo_df_codes['level']==input.my_tabs()],
df_summ = exit_velo_df_codes_summ[exit_velo_df_codes_summ['level']==input.my_tabs()],
player_id = input.id(),
stat_id = input.stat_id(),
batter_dict = batter_dict_ha,
window_select = input.n(),
level_id = input.my_tabs())
@output
@render.plot(alt="A histogram")
@reactive.event(input.go, ignore_none=False)
def plot_a():
rpf.rolling_plot(df = exit_velo_df_codes[exit_velo_df_codes['level']==input.my_tabs()],
df_summ = exit_velo_df_codes_summ[exit_velo_df_codes_summ['level']==input.my_tabs()],
player_id = input.id(),
stat_id = input.stat_id(),
batter_dict = batter_dict_a,
window_select = input.n(),
level_id = input.my_tabs())
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 Player'),
#ui.input_select("id", "Select Pitcher",batter_dict,selected=675911,width=1,size=1,selectize=True),
#ui.input_select("level_id", "Select Level",level_dict,width=1,size=1),
ui.input_select("stat_id", "Select Stat",plot_dict_small,width=1,size=1),
ui.input_numeric("n", "Rolling Window Size", value=50),
ui.input_action_button("go", "Generate",class_="btn-primary"),
ui.output_table("result")
),
ui.panel_main(
ui.navset_tab(
# ui.nav("Raw Data",
# ui.output_data_frame("raw_table")),
# ui.nav("Season Summary",
# ui.output_plot('plot',
# width='2000px',
# height='2000px')),
ui.nav("MLB",
ui.output_plot("plot_mlb",height = "1000px",width="1000px")),
ui.nav("AAA",
ui.output_plot("plot_aaa",height = "1000px",width="1000px")),
ui.nav("AA",
ui.output_plot("plot_aa",height = "1000px",width="1000px")),
ui.nav("A+",
ui.output_plot("plot_ha",height = "1000px",width="1000px")),
ui.nav("A",
ui.output_plot("plot_a",height = "1000px",width="1000px"))
,id="my_tabs")))))),server)