<jupyter_start><jupyter_text>**Statcast for Major League Baseball** Statcast is a state-of-the-art tracking system that uses high-resolution cameras and radar equipment to measure the precise location and movement of baseballs and baseball players. Introduced in 2015 to all 30 major league ballparks, Statcast data is revolutionizing the game.<jupyter_code>import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib
judge = pd.read_csv('/content/judge.csv')
stanton = pd.read_csv('/content/stanton.csv')
pd.set_option('display.max_columns',None)
judge.tail(5)<jupyter_output><empty_output><jupyter_text>**<NAME> and <NAME>, prolific sluggers**<jupyter_code># All of <NAME>'s batted ball events in 2017
judge_events_2017 = judge.loc[judge['game_year']==2017].events
print("<NAME> batted ball event totals, 2017:")
print(judge_events_2017.value_counts())
# All of <NAME>'s batted ball events in 2017
stanton_events_2017 = stanton.loc[stanton['game_year']==2017].events
print("\nGlancarlo Stanton batted ball event totals, 2017:")
print(stanton_events_2017.value_counts())<jupyter_output><NAME>on batted ball event totals, 2017:
field_out                    239
strikeout                    161
single                        77
walk                          72
home_run                      59
double                        32
grounded_into_double_play     13
intent_walk                   13
force_out                      7
hit_by_pitch                   7
field_error                    5
sac_fly                        3
strikeout_double_play          2
fielders_choice_out            2
pickoff_1b                     1
Name: events, dtype: int64<jupyter_text>**Analyzing home runs with Statcast data** So Judge walks and strikes out more than Stanton. Stanton flies out more than Judge. But let's get into their hitting profiles in more detail. Two of the most groundbreaking Statcast metrics are launch angle and exit velocity: Let's look at exit velocity vs. launch angle and let's focus on home runs only (2015-2017). The first two plots show data points. The second two show smoothed contours to represent density.<jupyter_code>#Home runs only
judge_hr=judge[judge['events']=='home_run']
stanton_hr=stanton[stanton['events']=='home_run']
#Scatter plots of launch speed vs. launch angle
fig1, axs1 = plt.subplots(ncols=2, sharex=True, sharey=True)
sns.regplot(x='launch_speed', y='launch_angle', fit_reg=False, color='tab:blue', data=judge_hr, ax=axs1[0]).set_title('Aaron Judge\nHome Runs, 2015-2017')
sns.regplot(x='launch_speed', y='launch_angle', fit_reg=False, color='tab:blue', data=stanton_hr, ax=axs1[1]).set_title('Giancarlo Stanton\nHome Runs, 2015-2017')

#KDE plots of launch speed vs. launch angle
fig2, axs2 = plt.subplots(ncols=2, sharex=True, sharey=True)
sns.kdeplot(judge_hr['launch_speed'], judge_hr['launch_angle'], cmap="Blues", shade=True, shade_lowest=False, ax=axs2[0]).set_title('Aaron Judge\nHome Runs, 2015-2017')
sns.kdeplot(stanton_hr['launch_speed'], stanton_hr['launch_angle'], cmap="Blues", shade=True, shade_lowest=False, ax=axs2[1]).set_title('Giancarlo Stanton\nHome Runs, 2015-2017')<jupyter_output>/usr/local/lib/python3.7/dist-packages/seaborn/_decorators.py:43: FutureWarning: Pass the following variable as a keyword arg: y. From version 0.12, the only valid positional argument will be `data`, and passing other arguments without an explicit keyword will result in an error or misinterpretation.
  FutureWarning
/usr/local/lib/python3.7/dist-packages/seaborn/distributions.py:1676: UserWarning: `shade_lowest` is now deprecated in favor of `thresh`. Setting `thresh=0.05`, but please update your code.
  warnings.warn(msg, UserWarning)
/usr/local/lib/python3.7/dist-packages/seaborn/_decorators.py:43: FutureWarning: Pass the following variable as a keyword arg: y. From version 0.12, the only valid positional argument will be `data`, and passing other arguments without an explicit keyword will result in an error or misinterpretation.
  FutureWarning
/usr/local/lib/python3.7/dist-packages/seaborn/distributions.py:1676: UserWarning: `shade_lowest` is now deprecated in favor of `thresh`. Se[...]<jupyter_text>**Home runs by pitch velocity**<jupyter_code># Combine the home run DataFrames for boxplot plotting
judge_stanton_hr = pd.concat([judge_hr,stanton_hr])

# Boxplot describes the pitch velocity of each player's home runs
sns.boxplot(x='player_name',y='release_speed',color='tab:blue',data=judge_stanton_hr).set_title('Home Runs, 2015-2017')<jupyter_output><empty_output><jupyter_text>**Home runs by pitch location** So Judge appears to hit his home runs off of faster pitches than Stanton. We might call Judge a fastball hitter. Stanton appears agnostic to pitch speed and likely pitch movement since slower pitches (e.g. curveballs, sliders, and changeups) tend to have more break. Statcast does track pitch movement and type but let's move on to something else: pitch location. Statcast tracks the zone the pitch is in when it crosses the plate. The zone numbering looks like this (from the catcher's point of view):We can plot this using a 2D histogram. For simplicity, let's only look at strikes, which gives us a 9x9 grid. We can view each zone as coordinates on a 2D plot, the bottom left corner being (1,1) and the top right corner being (3,3). Let's set up a function to assign x-coordinates to each pitch.<jupyter_code>def assign_x_coord(row):
    """
    Assigns an x-coordinate to Statcast's strike zone numbers. Zones 11, 12, 13,
    and 14 are ignored for plotting simplicity.
    """
    # Left third of strike zone
    if row.zone in [1, 4, 7]:
        return 1
    # Middle third of strike zone
    if row.zone in [2, 5, 8]:
        return 2
    # Right third of strike zone
    if row.zone in [3, 6, 9]:
           return 3<jupyter_output><empty_output><jupyter_text>**Home runs by pitch location**<jupyter_code>def assign_y_coord(row):
    """
    Assigns a y-coordinate to Statcast's strike zone numbers. Zones 11, 12, 13,
    and 14 are ignored for plotting simplicity.
    """
    # Upper third of strike zone
    if row.zone in [1, 2, 3]:
        return 3
    # Middle third of strike zone
    if row.zone in [4,5,6] :
        return 2
            
                      
    # Lower third of strike zone
    if row.zone in [7,8,9]:
        return 1<jupyter_output><empty_output><jupyter_text>**<NAME>'s home run zone**<jupyter_code># Zones 11, 12, 13, and 14 are to be ignored for plotting simplicity
judge_strike_hr = judge_hr.copy().loc[judge_hr.zone <= 9]

# Assign Cartesian coordinates to pitches in the strike zone for Judge home runs
judge_strike_hr['zone_x'] = judge_strike_hr.apply(assign_x_coord,axis=1)
judge_strike_hr['zone_y'] = judge_strike_hr.apply(assign_y_coord,axis=1)

# Plot Judge's home run zone as a 2D histogram with a colorbar
plt.hist2d(judge_strike_hr['zone_x'],judge_strike_hr['zone_y'], bins = 3, cmap='Blues')
plt.title('Aaron Judge Home Runs on\n Pitches in the Strike Zone, 2015-2017')
plt.gca().get_xaxis().set_visible(False)
plt.gca().get_yaxis().set_visible(False)
cb = plt.colorbar()
cb.set_label('Counts in Bin')<jupyter_output><empty_output><jupyter_text>**Giancarlo Stanton's home run zone**<jupyter_code># Zones 11, 12, 13, and 14 are to be ignored for plotting simplicity
stanton_strike_hr = stanton_hr.copy().loc[stanton_hr.zone <= 9]

# Assign Cartesian coordinates to pitches in the strike zone for Stanton home runs
stanton_strike_hr['zone_x'] = stanton_strike_hr.apply(assign_x_coord,axis=1)
stanton_strike_hr['zone_y'] = stanton_strike_hr.apply(assign_y_coord,axis=1)

# Plot Stanton's home run zone as a 2D histogram with a colorbar
plt.hist2d(stanton_strike_hr['zone_x'],stanton_strike_hr['zone_y'], bins = 3, cmap='Blues')
plt.title('Giancarlo Stanton Home Runs on\n Pitches in the Strike Zone, 2015-2017')
plt.gca().get_xaxis().set_visible(False)
plt.gca().get_yaxis().set_visible(False)
cb = plt.colorbar()
cb.set_label('Counts in Bin')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10006230529595016, 'fraction_numerical': 0.03264797507788162, 'mean_word_length': 4.445047489823609, 'pattern_counts': {'":': 0, '<': 40, '<?xml version=': 0, '>': 38, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '195806', 'license': 'CC-BY-3.0', 'n_tokens_mistral': 2807, 'n_tokens_neox': 2514, 'n_words': 817, 'path': 'Statcast.ipynb', 'repo_name': 'gerardbullock/New-Reposiitory', 'size': '8076'}