Update app.py
Browse files
app.py
CHANGED
|
@@ -43,6 +43,9 @@ st.markdown('<div class="main-container">', unsafe_allow_html=True)
|
|
| 43 |
markdown_text = """
|
| 44 |
## Catch Probability Lookup Tool
|
| 45 |
|
|
|
|
|
|
|
|
|
|
| 46 |
This Streamlit app retrieves catch probability data for a selected fielder from [Baseball Savant](https://baseballsavant.mlb.com/leaderboard/catch_probability).
|
| 47 |
The app displays the fielder's data in a table and allows the user to select a
|
| 48 |
row to view the corresponding catch video.
|
|
@@ -123,48 +126,55 @@ df_merge['catch_rate'] = df_merge['catch_rate'].astype(float).apply(lambda x: f"
|
|
| 123 |
df_merge['pos'] = df_merge['pos'].astype(int)
|
| 124 |
df_merge['Position'] = df_merge['pos'].map(pos_dict)
|
| 125 |
|
| 126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
|
| 128 |
-
column_names_display = ['Game Date','Batter Name', 'Pitcher Name', 'Fielder Name', 'Position','Event', 'Out', 'Wall', 'Back', 'Stars', 'Distance', 'Hang Time', 'Catch Rate']
|
| 129 |
|
| 130 |
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 |
-
# Use a container to control the width of the AgGrid display
|
| 135 |
-
with st.container():
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
|
| 143 |
|
| 144 |
-
|
| 145 |
-
|
| 146 |
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
|
| 156 |
-
# Get the selected row index
|
| 157 |
|
| 158 |
|
| 159 |
-
try:
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
except AttributeError:
|
| 168 |
-
|
| 169 |
|
| 170 |
st.markdown('</div>', unsafe_allow_html=True)
|
|
|
|
| 43 |
markdown_text = """
|
| 44 |
## Catch Probability Lookup Tool
|
| 45 |
|
| 46 |
+
##### By: Thomas Nestico ([@TJStats](https://x.com/TJStats))
|
| 47 |
+
##### Data: [MLB](https://baseballsavant.mlb.com/)
|
| 48 |
+
|
| 49 |
This Streamlit app retrieves catch probability data for a selected fielder from [Baseball Savant](https://baseballsavant.mlb.com/leaderboard/catch_probability).
|
| 50 |
The app displays the fielder's data in a table and allows the user to select a
|
| 51 |
row to view the corresponding catch video.
|
|
|
|
| 126 |
df_merge['pos'] = df_merge['pos'].astype(int)
|
| 127 |
df_merge['Position'] = df_merge['pos'].map(pos_dict)
|
| 128 |
|
| 129 |
+
df_merge = df_merge[df_merge['batter_id'] != df_merge['player_id']]
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
if df_merge.empty:
|
| 133 |
+
st.write("No data available for the selected fielder.")
|
| 134 |
+
st.stop()
|
| 135 |
+
else:
|
| 136 |
+
column_names = ['game_date','batter_name', 'pitcher_name', 'name_display_first_last', 'Position','event', 'out', 'wall', 'back', 'stars', 'distance', 'hang_time', 'catch_rate']
|
| 137 |
|
| 138 |
+
column_names_display = ['Game Date','Batter Name', 'Pitcher Name', 'Fielder Name', 'Position','Event', 'Out', 'Wall', 'Back', 'Stars', 'Distance', 'Hang Time', 'Catch Rate']
|
| 139 |
|
| 140 |
|
| 141 |
|
| 142 |
|
| 143 |
|
| 144 |
+
# Use a container to control the width of the AgGrid display
|
| 145 |
+
with st.container():
|
| 146 |
+
st.write("### Fielder Data")
|
| 147 |
+
# Configure the AgGrid options
|
| 148 |
+
gb = GridOptionsBuilder.from_dataframe(df_merge[column_names])
|
| 149 |
+
# Set display names for columns
|
| 150 |
+
for col, display_name in zip(column_names, column_names_display):
|
| 151 |
+
gb.configure_column(col, headerName=display_name)
|
| 152 |
|
| 153 |
|
| 154 |
+
gb.configure_selection('single', use_checkbox=True)
|
| 155 |
+
grid_options = gb.build()
|
| 156 |
|
| 157 |
+
# Display the dataframe using AgGrid
|
| 158 |
+
grid_response = AgGrid(
|
| 159 |
+
df_merge[column_names],
|
| 160 |
+
gridOptions=grid_options,
|
| 161 |
+
update_mode=GridUpdateMode.SELECTION_CHANGED,
|
| 162 |
+
height=300,
|
| 163 |
+
allow_unsafe_jscode=True,
|
| 164 |
+
)
|
| 165 |
|
| 166 |
+
# Get the selected row index
|
| 167 |
|
| 168 |
|
| 169 |
+
try:
|
| 170 |
+
# Update the video URL based on the selected row
|
| 171 |
+
selected_row_index = int(grid_response['selected_rows'].index.values[0])
|
| 172 |
+
a = requests.get(f'https://baseballsavant.mlb.com/sporty-videos?playId={df_merge["play_id"].values[selected_row_index]}')
|
| 173 |
+
soup = BeautifulSoup(a.content, 'lxml')
|
| 174 |
+
video_url = str(soup).split('<source src="')[1].split('" ')[0]
|
| 175 |
+
# Share the video through Streamlit
|
| 176 |
+
st.video(video_url)
|
| 177 |
+
except AttributeError:
|
| 178 |
+
st.write("Select Row to Display Video")
|
| 179 |
|
| 180 |
st.markdown('</div>', unsafe_allow_html=True)
|