patrickramos commited on
Commit
e5c3583
·
1 Parent(s): 024b191

Update app

Browse files
Files changed (3) hide show
  1. data.py +5 -0
  2. demo.py +95 -75
  3. gradio_function.py +5 -4
data.py CHANGED
@@ -153,6 +153,10 @@ df = (
153
  )
154
  ).sort(['game_pk', 'pa_pk', 'pitch_id'])
155
 
 
 
 
 
156
  pitch_stats, rhb_pitch_stats, lhb_pitch_stats = [
157
  (
158
  _df
@@ -164,6 +168,7 @@ pitch_stats, rhb_pitch_stats, lhb_pitch_stats = [
164
  pl.len().alias('Count')
165
  )
166
  .sort(['name', 'Count'], descending=[False, True])
 
167
  )
168
  for _df
169
  in (
 
153
  )
154
  ).sort(['game_pk', 'pa_pk', 'pitch_id'])
155
 
156
+ # add players to pa_df
157
+ # unfortunately we have pas that don't show up in the pitch data, so this would be useful for
158
+ pa_df = pa_df.join(player_df.rename({'player_id': 'pitcher'}), on='pitcher', how='inner')
159
+
160
  pitch_stats, rhb_pitch_stats, lhb_pitch_stats = [
161
  (
162
  _df
 
168
  pl.len().alias('Count')
169
  )
170
  .sort(['name', 'Count'], descending=[False, True])
171
+ .rename({'name': 'Player', 'pitch_name': 'Pitch'})
172
  )
173
  for _df
174
  in (
demo.py CHANGED
@@ -39,86 +39,106 @@ with gr.Blocks(
39
  app_pitch_stats = gr.State(pitch_stats)
40
  app_league_pitch_stats = gr.State(league_pitch_stats)
41
 
42
- with gr.Row():
43
- player = gr.Dropdown(value=None, choices=sorted(player_df.filter(pl.col('name').is_not_null())['name'].to_list()), label='Player')
44
- handedness = gr.Radio(value='Both', choices=['Both', 'Left', 'Right'], type='value', interactive=False, label='Batter Handedness')
 
45
 
46
- # preview = gr.DataFrame()
47
- download_file = gr.DownloadButton(label='Download player data')
48
 
49
- with gr.Group():
50
- with gr.Row():
51
- usage = gr.Plot(label='Pitch usage')
52
- velo_summary = gr.Plot(label='Velocity summary', elem_classes='pitch-velo-summary')
53
- loc_summary = gr.Plot(label='Overall location')
54
 
55
- max_locs = len(jp_pitch_to_en_pitch)
56
- locs_per_row = 4
57
- max_rows = ceil(max_locs/locs_per_row)
58
 
59
- gr.Markdown('''
60
- ## Pitch Locations
61
- Pitcher's persective
62
- <br>
63
- `NPB` refers to the top 10% of pitches thrown across the league with the current search constraints e.g. handedness
64
- <br>
65
- Note: To speed up the KDE, we restrict the league-wide pitches to 5,000 pitches
66
- ''')
67
- pitch_rows = []
68
- pitch_groups = []
69
- pitch_names = []
70
- pitch_infos = []
71
- pitch_velos = []
72
- pitch_locs = []
73
- for row in range(max_rows):
74
- visible = row==0
75
- pitch_row = gr.Row(visible=visible)
76
- pitch_rows.append(pitch_row)
77
- with pitch_row:
78
- _locs_per_row = locs_per_row if row < max_rows-1 else max_locs - locs_per_row * (max_rows - 1)
79
- for col in range(_locs_per_row):
80
- with gr.Column(min_width=256):
81
- pitch_group = gr.Group(visible=visible)
82
- pitch_groups.append(pitch_group)
83
- with pitch_group:
84
- pitch_names.append(gr.Markdown(f'### Pitch {col+1}', visible=visible))
85
- pitch_infos.append(gr.DataFrame(pl.DataFrame([{'Whiff%': None, 'CSW%': None}]), interactive=False, visible=visible))
86
- pitch_velos.append(gr.Plot(show_label=False, elem_classes='pitch-velo', visible=visible))
87
- pitch_locs.append(gr.Plot(label='Pitch Location', elem_classes='pitch-loc', visible=visible))
88
-
89
- gr.Markdown('## Pitch Velocity')
90
- velo_stats = gr.DataFrame(pl.DataFrame([{'Avg. Velo': None, 'League Avg. Velo': None}]), interactive=False, label='Pitch Velocity')
91
-
92
- (
93
- player
94
- .input(update_dfs, inputs=[player, handedness, source_df], outputs=[app_df, app_league_df, app_pitch_stats, app_league_pitch_stats])
95
- .then(lambda : gr.update(value='Both', interactive=True), outputs=handedness)
96
- )
97
- handedness.input(update_dfs, inputs=[player, handedness, source_df], outputs=[app_df, app_league_df, app_pitch_stats, app_league_pitch_stats])
98
-
99
- # app_df.change(preview_df, inputs=app_df, outputs=preview)
100
- # app_df.change(set_download_file, inputs=app_df, outputs=download_file)
101
- # app_df.change(plot_usage, inputs=[app_df, player], outputs=usage)
102
- # app_df.change(plot_velo_summary, inputs=[app_df, app_league_df, player], outputs=velo_summary)
103
- # app_df.change(lambda df: plot_loc(df), inputs=app_df, outputs=loc_summary)
104
- # app_df.change(plot_pitch_cards, inputs=[app_df, app_pitch_stats], outputs=pitch_rows+pitch_groups+pitch_names+pitch_infos+pitch_velos+pitch_locs)
105
- app_pitch_stats.change(update_velo_stats, inputs=[app_pitch_stats, app_league_pitch_stats], outputs=velo_stats)
106
-
107
- (
108
- app_df
109
- .change(set_download_file, inputs=app_df, outputs=download_file)
110
- .then(plot_usage, inputs=[app_df, player], outputs=usage)
111
- .then(plot_velo_summary, inputs=[app_df, app_league_df, player], outputs=velo_summary)
112
- .then(lambda df: plot_loc(df), inputs=app_df, outputs=loc_summary)
113
- .then(plot_pitch_cards, inputs=[app_df, app_league_df, app_pitch_stats], outputs=pitch_rows+pitch_groups+pitch_names+pitch_infos+pitch_velos+pitch_locs)
114
- )
115
-
116
- gr.Markdown('## Bugs and other notes')
117
- with gr.Accordion('Click to open', open=False):
118
  gr.Markdown('''
119
- - Y axis ticks messy when no velocity distribution is plotted
120
- - DataFrame precision inconsistent
121
- '''
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  )
123
 
124
  demo.launch(
 
39
  app_pitch_stats = gr.State(pitch_stats)
40
  app_league_pitch_stats = gr.State(league_pitch_stats)
41
 
42
+ with gr.Tab('Pitcher Dashboard'):
43
+ with gr.Row():
44
+ player = gr.Dropdown(value=None, choices=sorted(player_df.filter(pl.col('name').is_not_null())['name'].to_list()), label='Player')
45
+ handedness = gr.Radio(value='Both', choices=['Both', 'Left', 'Right'], type='value', interactive=False, label='Batter Handedness')
46
 
47
+ # preview = gr.DataFrame()
48
+ download_file = gr.DownloadButton(label='Download player data')
49
 
50
+ with gr.Group():
51
+ with gr.Row():
52
+ usage = gr.Plot(label='Pitch usage')
53
+ velo_summary = gr.Plot(label='Velocity summary', elem_classes='pitch-velo-summary')
54
+ loc_summary = gr.Plot(label='Overall location')
55
 
56
+ max_locs = len(jp_pitch_to_en_pitch)
57
+ locs_per_row = 4
58
+ max_rows = ceil(max_locs/locs_per_row)
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  gr.Markdown('''
61
+ ## Pitch Locations
62
+ Pitcher's persective
63
+ <br>
64
+ `NPB` refers to the top 10% of pitches thrown across the league with the current search constraints e.g. handedness
65
+ <br>
66
+ Note: To speed up the KDE, we restrict the league-wide pitches to 5,000 pitches
67
+ ''')
68
+ pitch_rows = []
69
+ pitch_groups = []
70
+ pitch_names = []
71
+ pitch_infos = []
72
+ pitch_velos = []
73
+ pitch_locs = []
74
+ for row in range(max_rows):
75
+ visible = row==0
76
+ pitch_row = gr.Row(visible=visible)
77
+ pitch_rows.append(pitch_row)
78
+ with pitch_row:
79
+ _locs_per_row = locs_per_row if row < max_rows-1 else max_locs - locs_per_row * (max_rows - 1)
80
+ for col in range(_locs_per_row):
81
+ with gr.Column(min_width=256):
82
+ pitch_group = gr.Group(visible=visible)
83
+ pitch_groups.append(pitch_group)
84
+ with pitch_group:
85
+ pitch_names.append(gr.Markdown(f'### Pitch {col+1}', visible=visible))
86
+ pitch_infos.append(gr.DataFrame(pl.DataFrame([{'Whiff%': None, 'CSW%': None}]), interactive=False, visible=visible))
87
+ pitch_velos.append(gr.Plot(show_label=False, elem_classes='pitch-velo', visible=visible))
88
+ pitch_locs.append(gr.Plot(label='Pitch Location', elem_classes='pitch-loc', visible=visible))
89
+
90
+ gr.Markdown('## Pitch Velocity')
91
+ velo_stats = gr.DataFrame(pl.DataFrame([{'Avg. Velo': None, 'League Avg. Velo': None}]), interactive=False, label='Pitch Velocity')
92
+
93
+ (
94
+ player
95
+ .input(update_dfs, inputs=[player, handedness, source_df], outputs=[app_df, app_league_df, app_pitch_stats, app_league_pitch_stats])
96
+ .then(lambda : gr.update(value='Both', interactive=True), outputs=handedness)
97
+ )
98
+ handedness.input(update_dfs, inputs=[player, handedness, source_df], outputs=[app_df, app_league_df, app_pitch_stats, app_league_pitch_stats])
99
+
100
+ # app_df.change(preview_df, inputs=app_df, outputs=preview)
101
+ # app_df.change(set_download_file, inputs=app_df, outputs=download_file)
102
+ # app_df.change(plot_usage, inputs=[app_df, player], outputs=usage)
103
+ # app_df.change(plot_velo_summary, inputs=[app_df, app_league_df, player], outputs=velo_summary)
104
+ # app_df.change(lambda df: plot_loc(df), inputs=app_df, outputs=loc_summary)
105
+ # app_df.change(plot_pitch_cards, inputs=[app_df, app_pitch_stats], outputs=pitch_rows+pitch_groups+pitch_names+pitch_infos+pitch_velos+pitch_locs)
106
+ app_pitch_stats.change(update_velo_stats, inputs=[app_pitch_stats, app_league_pitch_stats], outputs=velo_stats)
107
+
108
+ (
109
+ app_df
110
+ .change(create_set_download_file_fn('files/player.csv'), inputs=app_df, outputs=download_file)
111
+ .then(plot_usage, inputs=[app_df, player], outputs=usage)
112
+ .then(plot_velo_summary, inputs=[app_df, app_league_df, player], outputs=velo_summary)
113
+ .then(lambda df: plot_loc(df), inputs=app_df, outputs=loc_summary)
114
+ .then(plot_pitch_cards, inputs=[app_df, app_league_df, app_pitch_stats], outputs=pitch_rows+pitch_groups+pitch_names+pitch_infos+pitch_velos+pitch_locs)
115
+ )
116
+
117
+ gr.Markdown('## Bugs and other notes')
118
+ with gr.Accordion('Click to open', open=False):
119
+ gr.Markdown('''
120
+ - Y axis ticks messy when no velocity distribution is plotted
121
+ - DataFrame precision inconsistent
122
+ '''
123
+ )
124
+
125
+ with gr.Tab('Pitch Leaderboard'):
126
+ def filter_pitch_leaderboard(min_pitches):
127
+ return pitch_stats.filter(pl.col('Count') >= min_pitches).sort('CSW%', descending=True)
128
+
129
+ init_min_pitches = 100
130
+ pitch_stats.write_csv('pitch_leaderboard.csv')
131
+ pitch_leaderboard_df = gr.State(filter_pitch_leaderboard(init_min_pitches))
132
+
133
+ min_pitches = gr.Number(init_min_pitches, precision=0, label='Min. Pitches')
134
+ pitch_leaderboard_download_file = gr.DownloadButton(value='pitch_leaderboard.csv', label='Download leaderboard')
135
+ pitch_leaderboard = gr.Dataframe(value=pitch_leaderboard_df.value)
136
+
137
+ min_pitches.change(filter_pitch_leaderboard, inputs=min_pitches, outputs=pitch_leaderboard_df)
138
+ (
139
+ pitch_leaderboard_df
140
+ .change(create_set_download_file_fn('files/pitch_leaderboard.csv'), inputs=pitch_leaderboard_df, outputs=pitch_leaderboard_download_file)
141
+ .then(lambda df: df, inputs=pitch_leaderboard_df, outputs=pitch_leaderboard)
142
  )
143
 
144
  demo.launch(
gradio_function.py CHANGED
@@ -325,10 +325,11 @@ def update_dfs(player, handedness, df):
325
  final_filter = player_filter & handedness_filter
326
  return df.filter(final_filter), df.filter(handedness_filter), _pitch_stats.filter(player_filter), _league_pitch_stats,
327
 
328
- def set_download_file(df):
329
- file_path = 'files/npb.csv'
330
- df.write_csv(file_path)
331
- return file_path
 
332
 
333
  def preview_df(df):
334
  return df.head()
 
325
  final_filter = player_filter & handedness_filter
326
  return df.filter(final_filter), df.filter(handedness_filter), _pitch_stats.filter(player_filter), _league_pitch_stats,
327
 
328
+ def create_set_download_file_fn(filepath):
329
+ def set_download_file(df):
330
+ df.write_csv(filepath)
331
+ return filepath
332
+ return set_download_file
333
 
334
  def preview_df(df):
335
  return df.head()