import gradio as gr import pandas as pd from math import ceil import os from data import player_df from gradio_function import get_data from translate import jp_pitch_to_en_pitch, max_pitch_types os.makedirs('files', exist_ok=True) 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-velo-summary {height: 384px} .pitch-velo-summary .js-plotly-plot {height: 100%} ''' # display: flex; # align-items: center; # justify-content: center; 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() download_file = gr.DownloadButton(label='Download player data') 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(show_label=False, elem_classes='pitch-velo', visible=visible)) pitch_maps.append(gr.Plot(label='Pitch location', elem_classes='pitch-loc', visible=visible)) gr.Markdown('## Pitch Velocity') pitch_velo_summary = gr.Plot(show_label=False, elem_classes='pitch-velo-summary') 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, download_file, usage, *pitch_groups, *pitch_names, *pitch_infos, *pitch_velos, *pitch_maps, pitch_velo_summary]) demo.launch( share=True, debug=True )