Spaces:
Running
Running
Update functions/PitchPlotFunctions.py
Browse files- functions/PitchPlotFunctions.py +31 -47
functions/PitchPlotFunctions.py
CHANGED
|
@@ -13,7 +13,6 @@ import matplotlib.gridspec as gridspec
|
|
| 13 |
import matplotlib.patches as mpatches
|
| 14 |
import matplotlib.lines as mlines
|
| 15 |
from matplotlib.figure import Figure
|
| 16 |
-
# import streamlit as st
|
| 17 |
import api_scraper
|
| 18 |
|
| 19 |
# Initialize the scraper
|
|
@@ -311,83 +310,68 @@ class PitchPlotFunctions:
|
|
| 311 |
def break_plot_big(self, df: pl.DataFrame, ax: plt.Axes, sport_id: int):
|
| 312 |
"""
|
| 313 |
Plots a big break plot for the given DataFrame on the provided axis.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 314 |
"""
|
| 315 |
-
# Set font properties
|
| 316 |
font_properties = {'size': 10}
|
| 317 |
font_properties_titles = {'size': 16}
|
| 318 |
font_properties_axes = {'size': 14}
|
| 319 |
|
| 320 |
-
# Get unique pitch types
|
| 321 |
label_labels = df.sort(by=['prop', 'pitch_type'], descending=[False, True])['pitch_type'].unique()
|
|
|
|
| 322 |
dict_colour, dict_pitch = self.pitch_colours()
|
| 323 |
custom_theme, colour_palette = self.sns_custom_theme()
|
| 324 |
|
| 325 |
-
#
|
| 326 |
for label in label_labels:
|
| 327 |
subset = df.filter(pl.col('pitch_type') == label)
|
| 328 |
if len(subset) > 4:
|
| 329 |
try:
|
| 330 |
-
|
| 331 |
-
|
| 332 |
-
|
| 333 |
-
subset['ivb'],
|
| 334 |
-
ax=ax,
|
| 335 |
-
edgecolor=dict_colour[label],
|
| 336 |
-
n_std=2,
|
| 337 |
-
facecolor=dict_colour[label],
|
| 338 |
-
alpha=0.2
|
| 339 |
-
)
|
| 340 |
except ValueError:
|
| 341 |
return
|
|
|
|
|
|
|
|
|
|
| 342 |
|
| 343 |
-
# Plot scatter
|
| 344 |
-
|
| 345 |
-
|
| 346 |
-
|
| 347 |
-
x=df['hb'] *
|
| 348 |
-
y=df['ivb'],
|
| 349 |
-
hue=df['pitch_type'],
|
| 350 |
-
palette=dict_colour,
|
| 351 |
-
ec='black',
|
| 352 |
-
alpha=1,
|
| 353 |
-
zorder=2,
|
| 354 |
-
s=35
|
| 355 |
-
)
|
| 356 |
|
| 357 |
# Set plot limits and labels
|
| 358 |
ax.set_xlim((-25, 25))
|
| 359 |
ax.set_ylim((-25, 25))
|
| 360 |
ax.hlines(y=0, xmin=-50, xmax=50, color=colour_palette[8], alpha=0.5, linestyles='--', zorder=1)
|
| 361 |
ax.vlines(x=0, ymin=-50, ymax=50, color=colour_palette[8], alpha=0.5, linestyles='--', zorder=1)
|
| 362 |
-
|
| 363 |
-
|
| 364 |
-
ax.
|
| 365 |
-
ax.set_ylabel('Induced Vertical Break (in)', fontdict=font_properties_axes, labelpad=10)
|
| 366 |
-
ax.set_title(
|
| 367 |
-
f"{self.sport_id_dict()[sport_id]} - Short Form Pitch Movement Plot",
|
| 368 |
-
fontdict=font_properties_titles,
|
| 369 |
-
pad=20 # Add padding between title and plot
|
| 370 |
-
)
|
| 371 |
|
| 372 |
# Remove legend and set tick labels
|
| 373 |
ax.get_legend().remove()
|
| 374 |
ax.set_xticklabels(ax.get_xticks(), fontdict=font_properties)
|
| 375 |
ax.set_yticklabels(ax.get_yticks(), fontdict=font_properties)
|
| 376 |
|
| 377 |
-
# Add text annotations
|
| 378 |
if df['pitcher_hand'][0] == 'R':
|
| 379 |
-
ax.text(-24.5, -24.5, s='← Glove Side', fontstyle='italic', ha='left', va='bottom',
|
| 380 |
-
|
| 381 |
-
|
| 382 |
-
bbox=dict(facecolor='white', edgecolor='black'), fontsize=13, zorder=3)
|
| 383 |
-
else:
|
| 384 |
ax.invert_xaxis()
|
| 385 |
-
ax.text(24.5, -24.5, s='← Arm Side', fontstyle='italic', ha='left', va='bottom',
|
| 386 |
-
|
| 387 |
-
ax.text(-24.5, -24.5, s='Glove Side →', fontstyle='italic', ha='right', va='bottom',
|
| 388 |
-
bbox=dict(facecolor='white', edgecolor='black'), fontsize=13, zorder=3)
|
| 389 |
|
| 390 |
-
# Set aspect ratio and tick
|
| 391 |
ax.set_aspect('equal', adjustable='box')
|
| 392 |
ax.xaxis.set_major_formatter(FuncFormatter(lambda x, _: int(x)))
|
| 393 |
ax.yaxis.set_major_formatter(FuncFormatter(lambda x, _: int(x)))
|
|
|
|
| 13 |
import matplotlib.patches as mpatches
|
| 14 |
import matplotlib.lines as mlines
|
| 15 |
from matplotlib.figure import Figure
|
|
|
|
| 16 |
import api_scraper
|
| 17 |
|
| 18 |
# Initialize the scraper
|
|
|
|
| 310 |
def break_plot_big(self, df: pl.DataFrame, ax: plt.Axes, sport_id: int):
|
| 311 |
"""
|
| 312 |
Plots a big break plot for the given DataFrame on the provided axis.
|
| 313 |
+
|
| 314 |
+
Parameters:
|
| 315 |
+
df (pl.DataFrame): The DataFrame containing pitch data.
|
| 316 |
+
ax (plt.Axes): The matplotlib axis to plot on.
|
| 317 |
+
sport_id (int): The sport ID to determine the plot title.
|
| 318 |
"""
|
| 319 |
+
# Set font properties for different elements of the plot
|
| 320 |
font_properties = {'size': 10}
|
| 321 |
font_properties_titles = {'size': 16}
|
| 322 |
font_properties_axes = {'size': 14}
|
| 323 |
|
| 324 |
+
# Get unique pitch types sorted by 'prop' and 'pitch_type'
|
| 325 |
label_labels = df.sort(by=['prop', 'pitch_type'], descending=[False, True])['pitch_type'].unique()
|
| 326 |
+
j = 0
|
| 327 |
dict_colour, dict_pitch = self.pitch_colours()
|
| 328 |
custom_theme, colour_palette = self.sns_custom_theme()
|
| 329 |
|
| 330 |
+
# Loop through each pitch type and plot confidence ellipses
|
| 331 |
for label in label_labels:
|
| 332 |
subset = df.filter(pl.col('pitch_type') == label)
|
| 333 |
if len(subset) > 4:
|
| 334 |
try:
|
| 335 |
+
if df['pitcher_hand'][0] == 'R':
|
| 336 |
+
self.confidence_ellipse(subset['hb']* 1, subset['ivb'], ax=ax, edgecolor=dict_colour[label], n_std=2, facecolor=dict_colour[label], alpha=0.2)
|
| 337 |
+
if df['pitcher_hand'][0] == 'L':
|
| 338 |
+
self.confidence_ellipse(subset['hb'] * 1, subset['ivb'], ax=ax, edgecolor=dict_colour[label], n_std=2, facecolor=dict_colour[label], alpha=0.2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 339 |
except ValueError:
|
| 340 |
return
|
| 341 |
+
j += 1
|
| 342 |
+
else:
|
| 343 |
+
j += 1
|
| 344 |
|
| 345 |
+
# Plot scatter plot of pitch data
|
| 346 |
+
if df['pitcher_hand'][0] == 'R':
|
| 347 |
+
sns.scatterplot(ax=ax, x=df['hb'] * 1, y=df['ivb'] * 1, hue=df['pitch_type'], palette=dict_colour, ec='black', alpha=1, zorder=2, s=35)
|
| 348 |
+
if df['pitcher_hand'][0] == 'L':
|
| 349 |
+
sns.scatterplot(ax=ax, x=df['hb'] * 1, y=df['ivb'] * 1, hue=df['pitch_type'], palette=dict_colour, ec='black', alpha=1, zorder=2, s=35)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 350 |
|
| 351 |
# Set plot limits and labels
|
| 352 |
ax.set_xlim((-25, 25))
|
| 353 |
ax.set_ylim((-25, 25))
|
| 354 |
ax.hlines(y=0, xmin=-50, xmax=50, color=colour_palette[8], alpha=0.5, linestyles='--', zorder=1)
|
| 355 |
ax.vlines(x=0, ymin=-50, ymax=50, color=colour_palette[8], alpha=0.5, linestyles='--', zorder=1)
|
| 356 |
+
ax.set_xlabel('Horizontal Break (in)', fontdict=font_properties_axes)
|
| 357 |
+
ax.set_ylabel('Induced Vertical Break (in)', fontdict=font_properties_axes)
|
| 358 |
+
ax.set_title(f"{self.sport_id_dict()[sport_id]} - Short Form Pitch Movement Plot", fontdict=font_properties_titles)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 359 |
|
| 360 |
# Remove legend and set tick labels
|
| 361 |
ax.get_legend().remove()
|
| 362 |
ax.set_xticklabels(ax.get_xticks(), fontdict=font_properties)
|
| 363 |
ax.set_yticklabels(ax.get_yticks(), fontdict=font_properties)
|
| 364 |
|
| 365 |
+
# Add text annotations based on pitcher hand
|
| 366 |
if df['pitcher_hand'][0] == 'R':
|
| 367 |
+
ax.text(-24.5, -24.5, s='← Glove Side', fontstyle='italic', ha='left', va='bottom', bbox=dict(facecolor='white', edgecolor='black'), fontsize=13, zorder=3)
|
| 368 |
+
ax.text(24.5, -24.5, s='Arm Side →', fontstyle='italic', ha='right', va='bottom', bbox=dict(facecolor='white', edgecolor='black'), fontsize=13, zorder=3)
|
| 369 |
+
if df['pitcher_hand'][0] == 'L':
|
|
|
|
|
|
|
| 370 |
ax.invert_xaxis()
|
| 371 |
+
ax.text(24.5, -24.5, s='← Arm Side', fontstyle='italic', ha='left', va='bottom', bbox=dict(facecolor='white', edgecolor='black'), fontsize=13, zorder=3)
|
| 372 |
+
ax.text(-24.5, -24.5, s='Glove Side →', fontstyle='italic', ha='right', va='bottom', bbox=dict(facecolor='white', edgecolor='black'), fontsize=13, zorder=3)
|
|
|
|
|
|
|
| 373 |
|
| 374 |
+
# Set aspect ratio and format tick labels
|
| 375 |
ax.set_aspect('equal', adjustable='box')
|
| 376 |
ax.xaxis.set_major_formatter(FuncFormatter(lambda x, _: int(x)))
|
| 377 |
ax.yaxis.set_major_formatter(FuncFormatter(lambda x, _: int(x)))
|