patrickramos commited on
Commit
aaf4937
·
1 Parent(s): 26c325e

Update app

Browse files
Files changed (2) hide show
  1. demo.py +8 -1
  2. gradio_function.py +89 -2
demo.py CHANGED
@@ -17,6 +17,9 @@ css = '''
17
 
18
  .pitch-loc {height: 256px}
19
  .pitch-loc .js-plotly-plot {height: 100%}
 
 
 
20
  '''
21
  # .pitch-col {width: 256px !important}
22
  # .pitch-col .gr-group {width: 256px}
@@ -72,16 +75,20 @@ with gr.Blocks(css=css) as demo:
72
  pitch_velos.append(gr.Plot(label='Velocity distribution', elem_classes='pitch-velo', visible=visible))
73
  pitch_maps.append(gr.Plot(label='Pitch location', elem_classes='pitch-loc', visible=visible))
74
 
 
 
 
75
  gr.Markdown('## Bugs and other notes')
76
  with gr.Accordion('Click to open', open=False):
77
  gr.Markdown('''
78
  - Whiff% and CSW% has not been verified
79
  - No padding in pie charts leads to hovertext getting cut off near the bottom for some players
80
  - Y axis ticks messy when no velocity distribution is plotted
 
81
  '''
82
  )
83
 
84
- player.input(get_data, inputs=player, outputs=[player_info, usage, *pitch_groups, *pitch_names, *pitch_infos, *pitch_velos, *pitch_maps])
85
 
86
  demo.launch(
87
  share=True
 
17
 
18
  .pitch-loc {height: 256px}
19
  .pitch-loc .js-plotly-plot {height: 100%}
20
+
21
+ .pitch-velo-summary {height: 256px}
22
+ .pitch-velo-summary .js-plotly-plot {height: 100%}
23
  '''
24
  # .pitch-col {width: 256px !important}
25
  # .pitch-col .gr-group {width: 256px}
 
75
  pitch_velos.append(gr.Plot(label='Velocity distribution', elem_classes='pitch-velo', visible=visible))
76
  pitch_maps.append(gr.Plot(label='Pitch location', elem_classes='pitch-loc', visible=visible))
77
 
78
+ gr.Markdown('## Pitch Velocity')
79
+ pitch_velo_summary = gr.Plot(label='Velocity distribution', elem_classes='pitch-velo-summary')
80
+
81
  gr.Markdown('## Bugs and other notes')
82
  with gr.Accordion('Click to open', open=False):
83
  gr.Markdown('''
84
  - Whiff% and CSW% has not been verified
85
  - No padding in pie charts leads to hovertext getting cut off near the bottom for some players
86
  - Y axis ticks messy when no velocity distribution is plotted
87
+ - No padding in pitch velo chart leads to top row being hard to read
88
  '''
89
  )
90
 
91
+ player.input(get_data, inputs=player, outputs=[player_info, usage, *pitch_groups, *pitch_names, *pitch_infos, *pitch_velos, *pitch_maps, pitch_velo_summary])
92
 
93
  demo.launch(
94
  share=True
gradio_function.py CHANGED
@@ -90,6 +90,7 @@ pitch_stats = pd.merge(
90
  on=['name', 'pitch_name']
91
  ).set_index(['name', 'pitch_name'])
92
 
 
93
  # GRADIO FUNCTIONS
94
 
95
  # location maps
@@ -199,7 +200,7 @@ def plot_pitch_velo(player=None, velos=None, pitch_type=None, pitch_name=None):
199
  pitch_col = 'pitch_type' if pitch_type else 'pitch_name'
200
  velos = df.set_index(['name', pitch_col]).loc[(player, pitch_val), 'release_speed']
201
 
202
- fig = go.Figure(data=go.Violin(x=velos, side='positive', hoveron='points', name='Velocity Distribution'))
203
  fig.update_layout(
204
  xaxis=dict(
205
  title='Velocity',
@@ -221,6 +222,7 @@ def plot_pitch_velo(player=None, velos=None, pitch_type=None, pitch_name=None):
221
  )
222
  return fig
223
 
 
224
  def plot_empty_pitch_velo():
225
  fig = go.Figure()
226
  fig.add_annotation(
@@ -251,6 +253,90 @@ def plot_empty_pitch_velo():
251
  return fig
252
 
253
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  def get_data(player):
255
  player_name = f'# {player}'
256
 
@@ -297,5 +383,6 @@ def get_data(player):
297
  pitch_velos.append(gr.update(value=None, visible=False))
298
  pitch_maps.append(gr.update(value=None, visible=False))
299
 
 
300
 
301
- return player_name, usage_fig, *pitch_groups, *pitch_names, *pitch_infos, *pitch_velos, *pitch_maps
 
90
  on=['name', 'pitch_name']
91
  ).set_index(['name', 'pitch_name'])
92
 
93
+
94
  # GRADIO FUNCTIONS
95
 
96
  # location maps
 
200
  pitch_col = 'pitch_type' if pitch_type else 'pitch_name'
201
  velos = df.set_index(['name', pitch_col]).loc[(player, pitch_val), 'release_speed']
202
 
203
+ fig = go.Figure(data=go.Violin(x=velos, side='positive', hoveron='points', points=False, meanline_visible=True, name='Velocity Distribution'))
204
  fig.update_layout(
205
  xaxis=dict(
206
  title='Velocity',
 
222
  )
223
  return fig
224
 
225
+
226
  def plot_empty_pitch_velo():
227
  fig = go.Figure()
228
  fig.add_annotation(
 
253
  return fig
254
 
255
 
256
+ def plot_all_pitch_velo(player=None, player_df=None, pitch_counts=None, min_pitches=10):
257
+ # assert not ((player is None and player_df is None) or (player is not None and player_df is not None)), 'exactly one of `player` or `player_df` must be specified'
258
+
259
+ if player_df is None and player is not None:
260
+ assert pitch_counts is None, '`pitch_counts` must be `None` if `player_df` is None'
261
+ player_df = df.sort_values('name').set_index('name').loc[player].sort_values('pitch_name').set_index('pitch_name')
262
+ pitch_counts = player_df.index.value_counts(ascending=True)
263
+
264
+ league_df = df.set_index('pitch_name')
265
+
266
+ fig = go.Figure()
267
+
268
+ velo_center = (player_df['release_speed'].min() + player_df['release_speed'].max()) / 2
269
+ for i, (pitch_name, count) in enumerate(pitch_counts.items()):
270
+ velos = player_df.loc[pitch_name, 'release_speed']
271
+ league_velos = league_df.loc[pitch_name, 'release_speed']
272
+ fig.add_trace(go.Violin(
273
+ x=league_velos,
274
+ y=[pitch_name]*len(league_velos),
275
+ line_color='gray',
276
+ side='positive',
277
+ orientation='h',
278
+ meanline_visible=True,
279
+ points=False,
280
+ legendgroup='NPB',
281
+ legendrank=1,
282
+ # visible='legendonly',
283
+ showlegend=False,
284
+ name='NPB',
285
+ ))
286
+ if count >= min_pitches:
287
+ fig.add_trace(go.Violin(
288
+ x=velos,
289
+ y=[pitch_name]*len(velos),
290
+ side='positive',
291
+ orientation='h',
292
+ meanline_visible=True,
293
+ points=False,
294
+ legendgroup=pitch_name,
295
+ legendrank=2+i,
296
+ name=pitch_name
297
+ ))
298
+ else:
299
+ fig.add_trace(go.Scatter(
300
+ x=[velo_center],
301
+ y=[pitch_name],
302
+ text=['No visualization as less than 10 pitches thrown'],
303
+ textposition='top center',
304
+ hovertext=False,
305
+ mode="lines+text",
306
+ legendgroup=pitch_name,
307
+ legendrank=2+i,
308
+ name=pitch_name,
309
+ ))
310
+
311
+ fig.add_trace(go.Violin(
312
+ x=player_df['release_speed'],
313
+ y=[player]*len(player_df),
314
+ side='positive',
315
+ orientation='h',
316
+ meanline_visible=True,
317
+ points=False,
318
+ legendrank=0,
319
+ name=player
320
+ ))
321
+ fig.add_trace(go.Violin(
322
+ x=league_df['release_speed'],
323
+ y=[player]*len(league_df),
324
+ line_color='gray',
325
+ side='positive',
326
+ orientation='h',
327
+ meanline_visible=True,
328
+ points=False,
329
+ legendgroup='NPB',
330
+ legendrank=1,
331
+ # visible='legendonly',
332
+ name='NPB',
333
+ ))
334
+
335
+ fig.update_xaxes(title='Velocity')
336
+
337
+ return fig
338
+
339
+
340
  def get_data(player):
341
  player_name = f'# {player}'
342
 
 
383
  pitch_velos.append(gr.update(value=None, visible=False))
384
  pitch_maps.append(gr.update(value=None, visible=False))
385
 
386
+ pitch_velo_summary = plot_all_pitch_velo(player=player, player_df=_df_by_pitch_name, pitch_counts=pitch_counts)
387
 
388
+ return player_name, usage_fig, *pitch_groups, *pitch_names, *pitch_infos, *pitch_velos, *pitch_maps, pitch_velo_summary