nesticot commited on
Commit
ae22fb3
·
verified ·
1 Parent(s): 773a3cf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +265 -9
app.py CHANGED
@@ -254,9 +254,266 @@ def server(input,output,session):
254
 
255
 
256
 
257
- app = App(ui.page_fluid(
258
- ui.page_sidebar(
259
- ui.sidebar(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  ui.tags.h5("MLB & MiLB Rolling Batter Plot"),
261
  ui.tags.i("Baseball Analytics and Visualizations"),
262
  ui.div(
@@ -275,14 +532,14 @@ app = App(ui.page_fluid(
275
  )
276
  ),
277
  ui.row(
278
- ui.output_ui('test', 'Select Player'),
279
  ui.input_select("stat_id", "Select Stat", plot_dict_small, width=1, size=1),
280
  ui.input_numeric("n", "Rolling Window Size", value=50),
281
  ui.input_action_button("go", "Generate", class_="btn-primary"),
282
  ui.output_table("result")
283
  )
284
- )
285
- ,width='500px'
286
  ),
287
  ui.navset_tab(
288
  ui.nav("MLB", ui.output_plot("plot_mlb", height="1000px", width="1000px")),
@@ -293,6 +550,5 @@ app = App(ui.page_fluid(
293
  id="my_tabs"
294
  )
295
  ),
296
- )
297
- ,
298
- server)
 
254
 
255
 
256
 
257
+ from shiny import App, Inputs, Outputs, Session, reactive, render, req, ui
258
+ import datasets
259
+ from datasets import load_dataset
260
+ import pandas as pd
261
+ import numpy as np
262
+ import matplotlib.pyplot as plt
263
+ import seaborn as sns
264
+ import numpy as np
265
+ from scipy.stats import gaussian_kde
266
+ import matplotlib
267
+ from matplotlib.ticker import MaxNLocator
268
+ from matplotlib.gridspec import GridSpec
269
+ from scipy.stats import zscore
270
+ import math
271
+ import matplotlib
272
+ from adjustText import adjust_text
273
+ import matplotlib.ticker as mtick
274
+ from shinywidgets import output_widget, render_widget
275
+ import pandas as pd
276
+ #from configure import base_url
277
+ import shinyswatch
278
+ import inflect
279
+ from matplotlib.pyplot import text
280
+ from functions import rolling_batter_functions as rbf
281
+ import joblib
282
+ import polars as pl
283
+ from functions import df_update
284
+ update = df_update.df_update()
285
+
286
+ def percentile(n):
287
+ def percentile_(x):
288
+ return np.nanpercentile(x, n)
289
+ percentile_.__name__ = 'percentile_%s' % n
290
+ return percentile_
291
+
292
+ colour_palette = ['#FFB000','#648FFF','#785EF0',
293
+ '#DC267F','#FE6100','#3D1EB2','#894D80','#16AA02','#B5592B','#A3C1ED']
294
+
295
+
296
+
297
+ print('Starting Everything:')
298
+
299
+
300
+ exit_velo_df_mlb = pl.read_parquet(f"hf://datasets/TJStatsApps/mlb_data/data/mlb_pitch_data_2025.parquet")
301
+ #print(df_2023)
302
+ exit_velo_df_mlb = exit_velo_df_mlb.with_columns(pl.lit('MLB').alias('level'))
303
+
304
+
305
+ exit_velo_df_aaa = pl.read_parquet(f"hf://datasets/TJStatsApps/mlb_data/data/aaa_pitch_data_2025.parquet")
306
+ #print(df_2023)
307
+ exit_velo_df_aaa = exit_velo_df_aaa.with_columns(pl.lit('AAA').alias('level'))
308
+
309
+
310
+ exit_velo_df_aa = pl.read_parquet(f"hf://datasets/TJStatsApps/mlb_data/data/aa_pitch_data_2025.parquet")
311
+ #print(df_2023)
312
+ exit_velo_df_aa = exit_velo_df_aa.with_columns(pl.lit('AA').alias('level'))
313
+
314
+
315
+ exit_velo_df_ha = pl.read_parquet(f"hf://datasets/TJStatsApps/mlb_data/data/hi_a_pitch_data_2025.parquet")
316
+ #print(df_2023)
317
+ exit_velo_df_ha = exit_velo_df_ha.with_columns(pl.lit('A+').alias('level'))
318
+
319
+ ### Import Datasets
320
+ exit_velo_df_a = pl.read_parquet(f"hf://datasets/TJStatsApps/mlb_data/data/lo_a_pitch_data_2025.parquet")
321
+ #print(df_2023)
322
+ exit_velo_df_a = exit_velo_df_a.with_columns(pl.lit('A').alias('level'))
323
+
324
+
325
+
326
+ 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])
327
+ # 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])
328
+
329
+ exit_velo_df_codes = update.update(exit_velo_df)
330
+ exit_velo_df_codes_summ = update.update_summary_select(df=exit_velo_df_codes,selection=['batter_id','batter_name','level']).to_pandas()
331
+ exit_velo_df_codes = exit_velo_df_codes.to_pandas()
332
+
333
+ woba_list = ['woba']
334
+ pa_list = ['k','bb','bb_minus_k']
335
+ balls_in_play_list = ['hard_hit','launch_speed','launch_speed_90','launch_angle','barrel','sweet_spot']
336
+ pitches_list = ['zone_percent','swing_percent','sw_str','csw']
337
+ swings_list = ['whiff_percent']
338
+ in_zone_pitches_list = ['zone_swing']
339
+ in_zone_swings_list = ['zone_contact']
340
+ out_zone_pitches_list = ['chase_percent']
341
+ out_zone_swings_list = ['chase_contact']
342
+
343
+ plot_dict = {
344
+ '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},
345
+ '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},
346
+ '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},
347
+ '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},
348
+ '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},
349
+ '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},
350
+ '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},
351
+ '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},
352
+ '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},
353
+ '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},
354
+ '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},
355
+ '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},
356
+ '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},
357
+ '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},
358
+ '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},
359
+ '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},
360
+ '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},
361
+ '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},
362
+ '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},}
363
+
364
+
365
+
366
+
367
+ # 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()
368
+ # test_df = test_df.dropna()
369
+ # test_df['batter_id'] = test_df['batter_id'].astype(int)
370
+ # test_df = test_df.set_index('batter_id')
371
+ # #test_df = test_df[test_df.pitcher == 'Chris Bassitt'].append(test_df[test_df.pitcher != 'Chris Bassitt'])
372
+
373
+ batter_dict_mlb = dict(zip(exit_velo_df_mlb.sort(['batter_name'])['batter_id'],exit_velo_df_mlb.sort(['batter_name'])['batter_name']))
374
+ # batter_dict_mlb = exit_velo_df_mlb.sort(['batter_name']).set_index('batter_id')['batter_name'].to_dict()
375
+ batter_dict_aaa = dict(zip(exit_velo_df_aaa.sort(['batter_name'])['batter_id'],exit_velo_df_aaa.sort(['batter_name'])['batter_name']))
376
+ batter_dict_aa = dict(zip(exit_velo_df_aa.sort(['batter_name'])['batter_id'],exit_velo_df_aa.sort(['batter_name'])['batter_name']))
377
+ batter_dict_ha = dict(zip(exit_velo_df_ha.sort(['batter_name'])['batter_id'],exit_velo_df_ha.sort(['batter_name'])['batter_name']))
378
+ batter_dict_a =dict(zip(exit_velo_df_a.sort(['batter_name'])['batter_id'],exit_velo_df_a.sort(['batter_name'])['batter_name']))
379
+
380
+ level_dict = {'MLB':'MLB','AAA':'AAA','AA':'AA','A+':'A+','A':'A'}
381
+
382
+ plot_dict_small = {
383
+ 'k':'K%',
384
+ 'bb':'BB%',
385
+ 'bb_minus_k':'BB-K%',
386
+ 'csw':'CSW%',
387
+ 'woba':'wOBA',
388
+ 'launch_speed':'Exit Velocity',
389
+ 'launch_speed_90':'90th Percentile Exit Velocity',
390
+ 'hard_hit':'HardHit%',
391
+ 'sweet_spot':'SweetSpot%',
392
+ 'launch_angle':'Launch Angle',
393
+ 'zone_percent':'Zone%',
394
+ 'barrel':'Barrel%',
395
+ 'swing_percent':'Swing%',
396
+ 'whiff_percent':'Whiff%',
397
+ 'sw_str':'SwStr%',
398
+ 'zone_swing':'Z-Swing%',
399
+ 'zone_contact':'Z-Contact%',
400
+ 'chase_percent':'O-Swing%',
401
+ 'chase_contact':'O-Contact%',}
402
+
403
+
404
+ def server(input,output,session):
405
+
406
+ @render.ui
407
+ def test():
408
+
409
+ # @reactive.Effect
410
+ if input.my_tabs() == 'MLB':
411
+
412
+ #test_df = test_df[test_df.pitcher == 'Chris Bassitt'].append(test_df[test_df.pitcher != 'Chris Bassitt'])
413
+ #batter_dict = exit_velo_df_mlb.set_index('batter_id')['batter_name'].to_dict()
414
+ return ui.input_select("id", "Select Player",batter_dict_mlb,selectize=True)
415
+
416
+
417
+ if input.my_tabs() == 'AAA':
418
+ #test_df = test_df[test_df.pitcher == 'Chris Bassitt'].append(test_df[test_df.pitcher != 'Chris Bassitt'])
419
+ #batter_dict = exit_velo_df_aaa.set_index('batter_id')['batter_name'].to_dict()
420
+ return ui.input_select("id", "Select Player",batter_dict_aaa,selectize=True)
421
+
422
+ if input.my_tabs() == 'AA':
423
+ #test_df = test_df[test_df.pitcher == 'Chris Bassitt'].append(test_df[test_df.pitcher != 'Chris Bassitt'])
424
+ #batter_dict = exit_velo_df_aaa.set_index('batter_id')['batter_name'].to_dict()
425
+ return ui.input_select("id", "Select Player",batter_dict_aa,selectize=True)
426
+
427
+ if input.my_tabs() == 'A+':
428
+ #test_df = test_df[test_df.pitcher == 'Chris Bassitt'].append(test_df[test_df.pitcher != 'Chris Bassitt'])
429
+ #batter_dict = exit_velo_df_aaa.set_index('batter_id')['batter_name'].to_dict()
430
+ return ui.input_select("id", "Select Player",batter_dict_ha,selectize=True)
431
+
432
+ if input.my_tabs() == 'A':
433
+ #test_df = test_df[test_df.pitcher == 'Chris Bassitt'].append(test_df[test_df.pitcher != 'Chris Bassitt'])
434
+ #batter_dict = exit_velo_df_aaa.set_index('batter_id')['batter_name'].to_dict()
435
+ return ui.input_select("id", "Select Player",batter_dict_a,selectize=True)
436
+
437
+
438
+ @output
439
+ @render.plot(alt="A histogram")
440
+ @reactive.event(input.go, ignore_none=False)
441
+ def plot_mlb():
442
+
443
+
444
+ rbf.rolling_plot(df = exit_velo_df_codes[exit_velo_df_codes['level']==input.my_tabs()],
445
+ df_summ = exit_velo_df_codes_summ[exit_velo_df_codes_summ['level']==input.my_tabs()],
446
+ player_id = input.id(),
447
+ stat_id = input.stat_id(),
448
+ batter_dict = batter_dict_mlb,
449
+ window_select = input.n(),
450
+ level_id = input.my_tabs())
451
+
452
+
453
+ @output
454
+ @render.plot(alt="A histogram")
455
+ @reactive.event(input.go, ignore_none=False)
456
+ def plot_aaa():
457
+
458
+
459
+ rbf.rolling_plot(df = exit_velo_df_codes[exit_velo_df_codes['level']==input.my_tabs()],
460
+ df_summ = exit_velo_df_codes_summ[exit_velo_df_codes_summ['level']==input.my_tabs()],
461
+ player_id = input.id(),
462
+ stat_id = input.stat_id(),
463
+ batter_dict = batter_dict_aaa,
464
+ window_select = input.n(),
465
+ level_id = input.my_tabs())
466
+
467
+ @output
468
+ @render.plot(alt="A histogram")
469
+ @reactive.event(input.go, ignore_none=False)
470
+ def plot_aa():
471
+
472
+
473
+ rbf.rolling_plot(df = exit_velo_df_codes[exit_velo_df_codes['level']==input.my_tabs()],
474
+ df_summ = exit_velo_df_codes_summ[exit_velo_df_codes_summ['level']==input.my_tabs()],
475
+ player_id = input.id(),
476
+ stat_id = input.stat_id(),
477
+ batter_dict = batter_dict_aa,
478
+ window_select = input.n(),
479
+ level_id = input.my_tabs())
480
+ @output
481
+ @render.plot(alt="A histogram")
482
+ @reactive.event(input.go, ignore_none=False)
483
+ def plot_ha():
484
+
485
+
486
+ rbf.rolling_plot(df = exit_velo_df_codes[exit_velo_df_codes['level']==input.my_tabs()],
487
+ df_summ = exit_velo_df_codes_summ[exit_velo_df_codes_summ['level']==input.my_tabs()],
488
+ player_id = input.id(),
489
+ stat_id = input.stat_id(),
490
+ batter_dict = batter_dict_ha,
491
+ window_select = input.n(),
492
+ level_id = input.my_tabs())
493
+
494
+ @output
495
+ @render.plot(alt="A histogram")
496
+ @reactive.event(input.go, ignore_none=False)
497
+ def plot_a():
498
+
499
+
500
+ rbf.rolling_plot(df = exit_velo_df_codes[exit_velo_df_codes['level']==input.my_tabs()],
501
+ df_summ = exit_velo_df_codes_summ[exit_velo_df_codes_summ['level']==input.my_tabs()],
502
+ player_id = input.id(),
503
+ stat_id = input.stat_id(),
504
+ batter_dict = batter_dict_a,
505
+ window_select = input.n(),
506
+ level_id = input.my_tabs())
507
+
508
+
509
+
510
+
511
+
512
+
513
+ app = App(
514
+ ui.page_fluid(
515
+ ui.page_sidebar(
516
+ ui.sidebar(
517
  ui.tags.h5("MLB & MiLB Rolling Batter Plot"),
518
  ui.tags.i("Baseball Analytics and Visualizations"),
519
  ui.div(
 
532
  )
533
  ),
534
  ui.row(
535
+ ui.output_ui('test', 'Select Player'), # You may need to double check this line too
536
  ui.input_select("stat_id", "Select Stat", plot_dict_small, width=1, size=1),
537
  ui.input_numeric("n", "Rolling Window Size", value=50),
538
  ui.input_action_button("go", "Generate", class_="btn-primary"),
539
  ui.output_table("result")
540
  )
541
+ ),
542
+ width='500px'
543
  ),
544
  ui.navset_tab(
545
  ui.nav("MLB", ui.output_plot("plot_mlb", height="1000px", width="1000px")),
 
550
  id="my_tabs"
551
  )
552
  ),
553
+ server # ✅ server passed cleanly
554
+ )