patrickramos commited on
Commit
56c6bd4
·
1 Parent(s): e86b89f

Make leaderboard text smaller and add Zone% percentiles

Browse files
Files changed (4) hide show
  1. app.py +2 -1
  2. css.py +3 -0
  3. pitch_leaderboard.py +4 -2
  4. stats.py +1 -1
app.py CHANGED
@@ -3,6 +3,7 @@ import gradio as gr
3
  from data import data_df
4
  from pitcher_overview import create_pitcher_overview
5
  from pitch_leaderboard import create_pitch_leaderboard
 
6
 
7
  updated = '2025-07-21'
8
  limitations = '''**General Limitations**
@@ -10,7 +11,7 @@ limitations = '''**General Limitations**
10
  '''
11
 
12
  if __name__ == '__main__':
13
- with gr.Blocks() as app:
14
  with gr.Tab('Pitcher Overview'):
15
  create_pitcher_overview(data_df)
16
  with gr.Tab('Pitch Leaderboard'):
 
3
  from data import data_df
4
  from pitcher_overview import create_pitcher_overview
5
  from pitch_leaderboard import create_pitch_leaderboard
6
+ from css import css
7
 
8
  updated = '2025-07-21'
9
  limitations = '''**General Limitations**
 
11
  '''
12
 
13
  if __name__ == '__main__':
14
+ with gr.Blocks(css=css) as app:
15
  with gr.Tab('Pitcher Overview'):
16
  create_pitcher_overview(data_df)
17
  with gr.Tab('Pitch Leaderboard'):
css.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ css = '''
2
+ #leaderboard span {font-size: 0.75em;}
3
+ '''
pitch_leaderboard.py CHANGED
@@ -12,7 +12,7 @@ from plotting import stat_cmap
12
 
13
  STATS = ['Count', 'Usage', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'GB%', 'FB%', 'LD%', 'Zone%', 'Arm%', 'Glove%', 'High%', 'Low%', 'MM%']
14
  PCT_STATS = ['Usage', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'GB%', 'FB%', 'LD%', 'Zone%', 'Arm%', 'Glove%', 'High%', 'Low%', 'MM%']
15
- STATS_WITH_PCTLS = ['Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'GB%', 'FB%', 'LD%']
16
  COLUMNS = ['Pitcher', 'Team', 'Pitch', 'Pitch (General)'] + STATS
17
 
18
  PITCH_TYPES = [pitch_type for pitch_type in ball_kind.values() if pitch_type != '-']
@@ -84,6 +84,7 @@ def gr_create_pitch_leaderboard(start_date, end_date, min_pitches, pitcher_lr='B
84
  for i, row in enumerate(pitch_stats[COLUMNS].iter_rows()):
85
  styling_row = []
86
  for col, item in zip(pitch_stats[COLUMNS].columns, row):
 
87
  if f'{col}_pctl' in pitch_stats:
88
  r, g, b = (stat_cmap([pitch_stats[f'{col}_pctl'][i]])[0, :3]*255).astype(np.uint8)
89
  styling_row.append(f'background-color: rgba({r}, {g}, {b})')
@@ -141,10 +142,11 @@ def create_pitch_leaderboard():
141
  # pin_columns = gr.Checkbox(True, 'Pin columns')
142
  leaderboard = gr.DataFrame(
143
  pl.DataFrame({'Pitcher': [], 'Pitch': []}),
144
- column_widths=[200, 100, 200, 200] + [100]*len(STATS),
145
  show_copy_button=True,
146
  show_search='filter',
147
  pinned_columns=3,
 
148
  )
149
 
150
  gr.Markdown(notes)
 
12
 
13
  STATS = ['Count', 'Usage', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'GB%', 'FB%', 'LD%', 'Zone%', 'Arm%', 'Glove%', 'High%', 'Low%', 'MM%']
14
  PCT_STATS = ['Usage', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'GB%', 'FB%', 'LD%', 'Zone%', 'Arm%', 'Glove%', 'High%', 'Low%', 'MM%']
15
+ STATS_WITH_PCTLS = ['Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'GB%', 'FB%', 'LD%', 'Zone%']
16
  COLUMNS = ['Pitcher', 'Team', 'Pitch', 'Pitch (General)'] + STATS
17
 
18
  PITCH_TYPES = [pitch_type for pitch_type in ball_kind.values() if pitch_type != '-']
 
84
  for i, row in enumerate(pitch_stats[COLUMNS].iter_rows()):
85
  styling_row = []
86
  for col, item in zip(pitch_stats[COLUMNS].columns, row):
87
+ _styling = 'font-size: 0.75em; '
88
  if f'{col}_pctl' in pitch_stats:
89
  r, g, b = (stat_cmap([pitch_stats[f'{col}_pctl'][i]])[0, :3]*255).astype(np.uint8)
90
  styling_row.append(f'background-color: rgba({r}, {g}, {b})')
 
142
  # pin_columns = gr.Checkbox(True, 'Pin columns')
143
  leaderboard = gr.DataFrame(
144
  pl.DataFrame({'Pitcher': [], 'Pitch': []}),
145
+ column_widths=[125, 75, 125, 125] + [max(50, 10*len(stat)) for stat in STATS],
146
  show_copy_button=True,
147
  show_search='filter',
148
  pinned_columns=3,
149
+ elem_id='leaderboard'
150
  )
151
 
152
  gr.Markdown(notes)
stats.py CHANGED
@@ -102,7 +102,7 @@ def compute_pitch_stats(data, player_type, pitch_class_type, min_pitches=1):
102
  .drop('G', 'F', 'B', 'P', 'L', 'null')
103
  .with_columns(
104
  (pl.when(pl.col('qualified')).then(pl.col(stat)).rank(descending=((stat in ['FB%', 'LD%'] or 'Contact%' in stat)))/pl.when(pl.col('qualified')).then(pl.col(stat)).count()).alias(f'{stat}_pctl')
105
- for stat in ['Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'GB%', 'FB%', 'LD%']
106
  )
107
  .rename({pitch_col: 'ballKind_code', pitch_name_col: 'ballKind'} if pitch_class_type == 'general' else {})
108
  .sort(id_col, 'count', descending=[False, True])
 
102
  .drop('G', 'F', 'B', 'P', 'L', 'null')
103
  .with_columns(
104
  (pl.when(pl.col('qualified')).then(pl.col(stat)).rank(descending=((stat in ['FB%', 'LD%'] or 'Contact%' in stat)))/pl.when(pl.col('qualified')).then(pl.col(stat)).count()).alias(f'{stat}_pctl')
105
+ for stat in ['Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'GB%', 'FB%', 'LD%', 'Zone%']
106
  )
107
  .rename({pitch_col: 'ballKind_code', pitch_name_col: 'ballKind'} if pitch_class_type == 'general' else {})
108
  .sort(id_col, 'count', descending=[False, True])