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 from functions import rolling_batter_functions as rbf import joblib import polars as pl from functions import df_update update = df_update.df_update() 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_mlb = pl.read_parquet(f"hf://datasets/TJStatsApps/mlb_data/data/mlb_pitch_data_2025.parquet") #print(df_2023) exit_velo_df_mlb = exit_velo_df_mlb.with_columns(pl.lit('MLB').alias('level')) exit_velo_df_aaa = pl.read_parquet(f"hf://datasets/TJStatsApps/mlb_data/data/aaa_pitch_data_2025.parquet") #print(df_2023) exit_velo_df_aaa = exit_velo_df_aaa.with_columns(pl.lit('AAA').alias('level')) exit_velo_df_aa = pl.read_parquet(f"hf://datasets/TJStatsApps/mlb_data/data/aa_pitch_data_2025.parquet") #print(df_2023) exit_velo_df_aa = exit_velo_df_aa.with_columns(pl.lit('AA').alias('level')) exit_velo_df_ha = pl.read_parquet(f"hf://datasets/TJStatsApps/mlb_data/data/hi_a_pitch_data_2025.parquet") #print(df_2023) exit_velo_df_ha = exit_velo_df_ha.with_columns(pl.lit('A+').alias('level')) ### Import Datasets exit_velo_df_a = pl.read_parquet(f"hf://datasets/TJStatsApps/mlb_data/data/lo_a_pitch_data_2025.parquet") #print(df_2023) exit_velo_df_a = exit_velo_df_a.with_columns(pl.lit('A').alias('level')) exit_velo_df = pl.concat([exit_velo_df_mlb,exit_velo_df_aaa,exit_velo_df_aa,exit_velo_df_ha,exit_velo_df_a]) # exit_velo_df = pl.concat([exit_velo_df_mlb])#,exit_velo_df_aaa,exit_velo_df_aa,exit_velo_df_ha,exit_velo_df_a]) exit_velo_df_codes = update.update(exit_velo_df).sort('start_time') exit_velo_df_codes_summ = update.update_summary_select(df=exit_velo_df_codes,selection=['batter_id','batter_name','level']).to_pandas() exit_velo_df_codes = exit_velo_df_codes.to_pandas() woba_list = ['woba'] pa_list = ['k','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':True,'percentile':False,'avg_adjust':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':False,'percentile':False,'avg_adjust':False}, 'bb_minus_k':{'x_axis':'Plate Appearances','y_axis':'BB-K%','title':'BB-K%','x_value':'bb_minus_k','x_range':[-0.3,-0.2,-0.1,0,0.1,0.2],'percent':True,'percentile_label':'bb_minus_k_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':True,'percentile':False,'avg_adjust':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':False,'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],'percent':False,'percentile_label':'launch_speed','flip_p':False,'percentile':False,'avg_adjust':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':[95,100,105,110,115],'percent':False,'percentile_label':'launch_speed_90','flip_p':False,'percentile':True,'avg_adjust':False}, 'hard_hit':{'x_axis':'Balls In Play','y_axis':'HardHit%','title':'HardHit%','x_value':'hard_hit','x_range':[0.2,0.3,0.4,0.5,0.6,0.7],'percent':True,'percentile_label':'hard_hit_percent','flip_p':False,'percentile':False,'avg_adjust':False}, '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],'percent':True,'percentile_label':'sweet_spot_percent','flip_p':False,'percentile':False,'avg_adjust':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':False,'percentile':False,'avg_adjust':False}, 'barrel':{'x_axis':'Balls In Play','y_axis':'Barrel%','title':'Barrel%','x_value':'barrel','x_range':[0,0.05,0.10,.15,.20],'percent':True,'percentile_label':'barrel_percent','flip_p':False,'percentile':False,'avg_adjust':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,'avg_adjust':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,'avg_adjust':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':True,'percentile':False,'avg_adjust':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':True,'percentile':False,'avg_adjust':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':False,'percentile':False,'avg_adjust':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':False,'percentile':False,'avg_adjust':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':True,'percentile':False,'avg_adjust':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':False,'percentile':False,'avg_adjust':False},} # test_df = exit_velo_df.sort_values(by='batter_name').drop_duplicates(subset='batter_id').reset_index(drop=True)[['batter_id','batter_name']]#['pitcher'].to_dict() # test_df = test_df.dropna() # test_df['batter_id'] = test_df['batter_id'].astype(int) # test_df = test_df.set_index('batter_id') # #test_df = test_df[test_df.pitcher == 'Chris Bassitt'].append(test_df[test_df.pitcher != 'Chris Bassitt']) batter_dict_mlb = dict(zip(exit_velo_df_mlb.sort(['batter_name'])['batter_id'],exit_velo_df_mlb.sort(['batter_name'])['batter_name'])) # batter_dict_mlb = exit_velo_df_mlb.sort(['batter_name']).set_index('batter_id')['batter_name'].to_dict() batter_dict_aaa = dict(zip(exit_velo_df_aaa.sort(['batter_name'])['batter_id'],exit_velo_df_aaa.sort(['batter_name'])['batter_name'])) batter_dict_aa = dict(zip(exit_velo_df_aa.sort(['batter_name'])['batter_id'],exit_velo_df_aa.sort(['batter_name'])['batter_name'])) batter_dict_ha = dict(zip(exit_velo_df_ha.sort(['batter_name'])['batter_id'],exit_velo_df_ha.sort(['batter_name'])['batter_name'])) batter_dict_a =dict(zip(exit_velo_df_a.sort(['batter_name'])['batter_id'],exit_velo_df_a.sort(['batter_name'])['batter_name'])) level_dict = {'MLB':'MLB','AAA':'AAA','AA':'AA','A+':'A+','A':'A'} plot_dict_small = { 'k':'K%', 'bb':'BB%', 'bb_minus_k':'BB-K%', 'csw':'CSW%', 'woba':'wOBA', 'launch_speed':'Exit Velocity', 'launch_speed_90':'90th Percentile Exit Velocity', 'hard_hit':'HardHit%', '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(): rbf.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(): rbf.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(): rbf.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(): rbf.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(): rbf.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()) 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 from functions import rolling_batter_functions as rbf import joblib import polars as pl from functions import df_update update = df_update.df_update() 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_mlb = pl.read_parquet(f"hf://datasets/TJStatsApps/mlb_data/data/mlb_pitch_data_2025.parquet") #print(df_2023) exit_velo_df_mlb = exit_velo_df_mlb.with_columns(pl.lit('MLB').alias('level')) exit_velo_df_aaa = pl.read_parquet(f"hf://datasets/TJStatsApps/mlb_data/data/aaa_pitch_data_2025.parquet") #print(df_2023) exit_velo_df_aaa = exit_velo_df_aaa.with_columns(pl.lit('AAA').alias('level')) exit_velo_df_aa = pl.read_parquet(f"hf://datasets/TJStatsApps/mlb_data/data/aa_pitch_data_2025.parquet") #print(df_2023) exit_velo_df_aa = exit_velo_df_aa.with_columns(pl.lit('AA').alias('level')) exit_velo_df_ha = pl.read_parquet(f"hf://datasets/TJStatsApps/mlb_data/data/hi_a_pitch_data_2025.parquet") #print(df_2023) exit_velo_df_ha = exit_velo_df_ha.with_columns(pl.lit('A+').alias('level')) ### Import Datasets exit_velo_df_a = pl.read_parquet(f"hf://datasets/TJStatsApps/mlb_data/data/lo_a_pitch_data_2025.parquet") #print(df_2023) exit_velo_df_a = exit_velo_df_a.with_columns(pl.lit('A').alias('level')) exit_velo_df = pl.concat([exit_velo_df_mlb,exit_velo_df_aaa,exit_velo_df_aa,exit_velo_df_ha,exit_velo_df_a]) # exit_velo_df = pl.concat([exit_velo_df_mlb])#,exit_velo_df_aaa,exit_velo_df_aa,exit_velo_df_ha,exit_velo_df_a]) exit_velo_df_codes = update.update(exit_velo_df) exit_velo_df_codes_summ = update.update_summary_select(df=exit_velo_df_codes,selection=['batter_id','batter_name','level']).to_pandas() exit_velo_df_codes = exit_velo_df_codes.to_pandas() woba_list = ['woba'] pa_list = ['k','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':True,'percentile':False,'avg_adjust':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':False,'percentile':False,'avg_adjust':False}, 'bb_minus_k':{'x_axis':'Plate Appearances','y_axis':'BB-K%','title':'BB-K%','x_value':'bb_minus_k','x_range':[-0.3,-0.2,-0.1,0,0.1,0.2],'percent':True,'percentile_label':'bb_minus_k_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':True,'percentile':False,'avg_adjust':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':False,'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],'percent':False,'percentile_label':'launch_speed','flip_p':False,'percentile':False,'avg_adjust':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':[95,100,105,110,115],'percent':False,'percentile_label':'launch_speed_90','flip_p':False,'percentile':True,'avg_adjust':False}, 'hard_hit':{'x_axis':'Balls In Play','y_axis':'HardHit%','title':'HardHit%','x_value':'hard_hit','x_range':[0.2,0.3,0.4,0.5,0.6,0.7],'percent':True,'percentile_label':'hard_hit_percent','flip_p':False,'percentile':False,'avg_adjust':False}, '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],'percent':True,'percentile_label':'sweet_spot_percent','flip_p':False,'percentile':False,'avg_adjust':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':False,'percentile':False,'avg_adjust':False}, 'barrel':{'x_axis':'Balls In Play','y_axis':'Barrel%','title':'Barrel%','x_value':'barrel','x_range':[0,0.05,0.10,.15,.20],'percent':True,'percentile_label':'barrel_percent','flip_p':False,'percentile':False,'avg_adjust':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,'avg_adjust':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,'avg_adjust':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':True,'percentile':False,'avg_adjust':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':True,'percentile':False,'avg_adjust':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':False,'percentile':False,'avg_adjust':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':False,'percentile':False,'avg_adjust':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':True,'percentile':False,'avg_adjust':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':False,'percentile':False,'avg_adjust':False},} # test_df = exit_velo_df.sort_values(by='batter_name').drop_duplicates(subset='batter_id').reset_index(drop=True)[['batter_id','batter_name']]#['pitcher'].to_dict() # test_df = test_df.dropna() # test_df['batter_id'] = test_df['batter_id'].astype(int) # test_df = test_df.set_index('batter_id') # #test_df = test_df[test_df.pitcher == 'Chris Bassitt'].append(test_df[test_df.pitcher != 'Chris Bassitt']) batter_dict_mlb = dict(zip(exit_velo_df_mlb.sort(['batter_name'])['batter_id'],exit_velo_df_mlb.sort(['batter_name'])['batter_name'])) # batter_dict_mlb = exit_velo_df_mlb.sort(['batter_name']).set_index('batter_id')['batter_name'].to_dict() batter_dict_aaa = dict(zip(exit_velo_df_aaa.sort(['batter_name'])['batter_id'],exit_velo_df_aaa.sort(['batter_name'])['batter_name'])) batter_dict_aa = dict(zip(exit_velo_df_aa.sort(['batter_name'])['batter_id'],exit_velo_df_aa.sort(['batter_name'])['batter_name'])) batter_dict_ha = dict(zip(exit_velo_df_ha.sort(['batter_name'])['batter_id'],exit_velo_df_ha.sort(['batter_name'])['batter_name'])) batter_dict_a =dict(zip(exit_velo_df_a.sort(['batter_name'])['batter_id'],exit_velo_df_a.sort(['batter_name'])['batter_name'])) level_dict = {'MLB':'MLB','AAA':'AAA','AA':'AA','A+':'A+','A':'A'} plot_dict_small = { 'k':'K%', 'bb':'BB%', 'bb_minus_k':'BB-K%', 'csw':'CSW%', 'woba':'wOBA', 'launch_speed':'Exit Velocity', 'launch_speed_90':'90th Percentile Exit Velocity', 'hard_hit':'HardHit%', '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(): rbf.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(): rbf.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(): rbf.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(): rbf.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(): rbf.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.page_sidebar( ui.sidebar( ui.tags.h5("MLB & MiLB Rolling Batter Plot"), ui.tags.i("Baseball Analytics and Visualizations"), ui.div( "By: ", ui.tags.a( "@TJStats", href="https://x.com/TJStats", target="_blank" ) ), ui.tags.p( ui.tags.a( "Support me on Patreon for more baseball content", href="https://www.patreon.com/TJ_Stats", target="_blank" ) ), ui.row( ui.output_ui('test', 'Select Player'), # You may need to double check this line too 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") ) ,width='500px'), ui.navset_tab( 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 # ✅ server passed cleanly )