File size: 3,180 Bytes
41bdb13
 
9d7970d
41bdb13
9d7970d
41bdb13
9d7970d
 
41bdb13
 
26c325e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41bdb13
 
 
 
 
 
26c325e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41bdb13
9d7970d
26c325e
9d7970d
 
26c325e
 
 
 
 
9d7970d
 
26c325e
9d7970d
 
 
26c325e
 
9d7970d
26c325e
 
 
 
 
 
 
 
9d7970d
 
 
 
26c325e
 
 
9d7970d
 
 
26c325e
9d7970d
 
 
26c325e
9d7970d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

import gradio as gr
import pandas as pd

from math import ceil

from gradio_function import player_df, jp_pitch_to_en_pitch, get_data
from translate import max_pitch_types


css = '''
.pitch-usage {height: 256px}
.pitch-usage .js-plotly-plot {height: 100%}

.pitch-velo {height: 100px}
.pitch-velo .js-plotly-plot {height: 100%}

.pitch-loc {height: 256px}
.pitch-loc .js-plotly-plot {height: 100%}
'''
# .pitch-col {width: 256px !important}
# .pitch-col .gr-group {width: 256px}
# .pitch-col .js-plotly-plot {width: 100%}

with gr.Blocks(css=css) as demo:
  gr.Markdown('''
  # NPB data visualization demo
  [Data from SportsNavi](https://sports.yahoo.co.jp/)
  ''')
  player = gr.Dropdown(choices=sorted(player_df['name'].dropna().tolist()), label='Player')
  player_info = gr.Markdown()
  with gr.Row():
    with gr.Column():
      gr.Markdown('## Placeholder')
      # with gr.Group():
      #   gr.Markdown('''## Percentile rankings (layout and values are placeholders)''')
      #   import numpy as np
      #   stats = np.array(['RV', 'Fastball RV', 'Breaking FV', 'Offspeed RV', 'K%', 'BB%', 'xwOBA', 'xwOBAcon'])
      #   for _stats in stats.reshape(2, -1).T:
      #     with gr.Row():
      #       for stat in _stats:
      #         gr.Slider(label=stat, value=100, minimum=0, maximum=100, step=1, min_width=256)
      #         gr.Markdown('100')
    with gr.Column():
      gr.Markdown('## Pitch Distribution')
      usage = gr.Plot(label='Pitch Distribution', elem_classes='pitch-usage')

  max_pitch_maps = len(jp_pitch_to_en_pitch)
  pitch_maps_per_row = 4
  max_rows = ceil(max_pitch_maps/pitch_maps_per_row)

  gr.Markdown('''
  ## Pitch Locations
  Pitcher's persective
  ''')
  pitch_groups = []
  pitch_names = []
  pitch_infos = []
  pitch_velos = []
  pitch_maps = []
  for row in range(max_rows):
    with gr.Row():
      _pitch_maps_per_row = pitch_maps_per_row if row < max_rows-1 else max_pitch_maps - pitch_maps_per_row * (max_rows - 1)
      visible = row==0
      for col in range(_pitch_maps_per_row):
        with gr.Column(elem_classes='pitch-col', min_width=256):
          pitch_group = gr.Group(visible=visible)
          pitch_groups.append(pitch_group)
          with pitch_group:
            pitch_names.append(gr.Markdown(f'### Pitch {col+1}', visible=visible))
            pitch_infos.append(gr.DataFrame(pd.DataFrame([{'Whiff%': None, 'CSW%': None}]), interactive=False, visible=visible))
            pitch_velos.append(gr.Plot(label='Velocity distribution', elem_classes='pitch-velo', visible=visible))
            pitch_maps.append(gr.Plot(label='Pitch location', elem_classes='pitch-loc', visible=visible))

  gr.Markdown('## Bugs and other notes')
  with gr.Accordion('Click to open', open=False):
    gr.Markdown('''
    - Whiff% and CSW% has not been verified
    - No padding in pie charts leads to hovertext getting cut off near the bottom for some players
    - Y axis ticks messy when no velocity distribution is plotted
    '''
    )

  player.input(get_data, inputs=player, outputs=[player_info, usage, *pitch_groups, *pitch_names, *pitch_infos, *pitch_velos, *pitch_maps])

demo.launch(
    share=True
    # debug=True
)