藤浪投手のデータを確認しつつ、各選手への投球結果(何球目など)をグラフに表示。
グラフの題名に対戦選手名を入れる方法を探った
データ取得
!pip install pybaseball
from pybaseball import statcast
import pandas as pd
from pybaseball import statcast
dates = [
'2023-04-01', '2023-04-08', '2023-04-15'
]
# Create an empty DataFrame to store the data
df_660261_all_dates = pd.DataFrame()
# Fetch data for each date and concatenate
for date in dates:
df_single_day = statcast(start_dt=date, end_dt=date)
df_660261_single_day = df_single_day[df_single_day['pitcher'] == 660261]
df_660261_all_dates = pd.concat([df_660261_all_dates, df_660261_single_day])
# Reset the index of the final DataFrame
df_660261_all_dates.reset_index(drop=True, inplace=True)
球種
# 投球結果を抽出
df_660261 = df_660261_all_dates
# df_660261のpitch_typeカラムに含まれるユニークな球種を確認する
unique_pitch_types = df_660261['pitch_type'].unique()
# 確認した球種を表示する
print(unique_pitch_types)
結果
['FF' 'SL' 'FS' 'ST' 'CU' 'SI']
- FF: Four-Seam Fastball - 4シームファストボール
- SL: Slider - スライダー
- FS: Splitter - スプリッター
- ST: Slutter - スライダー or カッター
- CU: Curveball - カーブ
- SI: Sinker - シンカー (2シームファストボール)
球種カウント
import pandas as pd
def pitch_counts(df):
# 左打者と右打者に対する投球データを抽出
df_L = df[df['stand'] == 'L']
df_R = df[df['stand'] == 'R']
# 各カテゴリーでの球種の出現回数をカウント
total_counts = df['pitch_type'].value_counts()
left_counts = df_L['pitch_type'].value_counts()
right_counts = df_R['pitch_type'].value_counts()
# 出現回数をデータフレームにまとめる
pitch_counts_table = pd.DataFrame({'Total': total_counts, 'Left Batter': left_counts, 'Right Batter': right_counts})
# NaNを0に置き換える
pitch_counts_table.fillna(0, inplace=True)
# カウントを整数に変換する
pitch_counts_table = pitch_counts_table.astype(int)
return pitch_counts_table
# 続けて、球種カウントのコードを実行します。
# Split the data by date
df_0401 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-01']
df_0408 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-08']
df_0415 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-15']
# Get pitch counts for each date
pitch_counts_0401 = pitch_counts(df_0401)
pitch_counts_0408 = pitch_counts(df_0408)
pitch_counts_0415 = pitch_counts(df_0415)
# Display the results
print("2023年4月1日の球種カウント:")
print(pitch_counts_0401)
print("\n2023年4月8日の球種カウント:")
print(pitch_counts_0408)
print("\n2023年4月15日の球種カウント:")
print(pitch_counts_0415)
球種カウント(円グラフ)
import matplotlib.pyplot as plt
def plot_pitch_distribution(df, date):
df_L = df[df['stand'] == 'L']
df_R = df[df['stand'] == 'R']
fig, axs = plt.subplots(1, 3, figsize=(18, 6))
plt.suptitle(f'Pitch Distribution on {date}')
colors = {'FF': 'red', 'SL': 'blue', 'FS': 'green', 'ST': 'orange', 'CU': 'purple', 'SI': 'brown'}
# Total
df['pitch_type'].value_counts().plot(kind='pie', ax=axs[0], autopct='%.1f%%', colors=[colors[key] for key in df['pitch_type'].value_counts().index])
axs[0].set_title('Total')
axs[0].set_ylabel('')
# vs Left batter
df_L['pitch_type'].value_counts().plot(kind='pie', ax=axs[1], autopct='%.1f%%', colors=[colors[key] for key in df_L['pitch_type'].value_counts().index])
axs[1].set_title('vs Left batter')
axs[1].set_ylabel('')
# vs Right batter
df_R['pitch_type'].value_counts().plot(kind='pie', ax=axs[2], autopct='%.1f%%', colors=[colors[key] for key in df_R['pitch_type'].value_counts().index])
axs[2].set_title('vs Right batter')
axs[2].set_ylabel('')
plt.show()
df_2023_04_01 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-01']
df_2023_04_08 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-08']
df_2023_04_15 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-15']
plot_pitch_distribution(df_2023_04_01, '2023-04-01')
plot_pitch_distribution(df_2023_04_08, '2023-04-08')
plot_pitch_distribution(df_2023_04_15, '2023-04-15')
投球コース
import matplotlib.pyplot as plt
def plot_pitch_location(df, date):
# データを pitch_type ごとにグループ分けする
grouped = df.groupby('pitch_type')
colors = {'FF': 'red', 'SL': 'blue', 'FS': 'green', 'ST': 'orange', 'CU': 'purple', 'SI': 'brown'}
# pitch_type ごとに、'plate_x' を X 軸、'plate_z' を Y 軸とした散布図を作成する
for pitch_type, data in grouped:
plt.scatter(data['plate_x'], data['plate_z'], label=pitch_type, color=colors[pitch_type])
# ストライクゾーン
x = [-0.88, 0.88, 0.88, -0.88, -0.88]
y = [1.51, 1.51, 3.4, 3.4, 1.51]
plt.fill(x, y, color='r', alpha=0.3)
# 凡例を表示する
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0)
plt.xlim(-3, 4)
plt.ylim(-3, 7)
plt.xlabel('Plate X')
plt.ylabel('Plate Z')
# 罫線
plt.grid(which='both', linestyle='--', color='gray', alpha=0.5)
plt.title(f'Pitch Location on {date}')
# グラフを表示する
plt.show()
df_2023_04_01 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-01']
df_2023_04_08 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-08']
df_2023_04_15 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-15']
plot_pitch_location(df_2023_04_01, '2023-04-01')
plot_pitch_location(df_2023_04_08, '2023-04-08')
plot_pitch_location(df_2023_04_15, '2023-04-15')
投球コース(球種ごと)
import matplotlib.pyplot as plt
def plot_pitch_location_by_date(df_1, df_2, df_3):
combined_df = pd.concat([df_1, df_2, df_3])
grouped = combined_df.groupby('pitch_type')
nrows = 3
ncols = 2
titles = []
fig, axes = plt.subplots(nrows=nrows, ncols=ncols, figsize=(10, 15))
for idx, (pitch_type, data) in enumerate(grouped):
titles.append(pitch_type)
row = idx // ncols
col = idx % ncols
ax = axes[row][col]
data_1 = data[data.index.isin(df_1.index)]
data_2 = data[data.index.isin(df_2.index)]
data_3 = data[data.index.isin(df_3.index)]
ax.scatter(data_1['plate_x'], data_1['plate_z'], label='2023-04-01', color='blue')
ax.scatter(data_2['plate_x'], data_2['plate_z'], label='2023-04-08', color='red')
ax.scatter(data_3['plate_x'], data_3['plate_z'], label='2023-04-15', color='green')
x = [-0.88, 0.88, 0.88, -0.88, -0.88]
y = [1.51, 1.51, 3.4, 3.4, 1.51]
ax.fill(x, y, color='r', alpha=0.3)
ax.set_title(pitch_type)
ax.set_xlabel('Plate X')
ax.set_ylabel('Plate Z')
ax.grid(which='both', linestyle='--', color='gray', alpha=0.5)
ax.legend()
ax.set_xlim(-3, 4) # X軸の最小値と最大値を設定
ax.set_ylim(-3, 7) # Y軸の最小値と最大値を設定
plt.tight_layout()
plt.show()
df_2023_04_01 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-01']
df_2023_04_08 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-08']
df_2023_04_15 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-15']
plot_pitch_location_by_date(df_2023_04_01, df_2023_04_08, df_2023_04_15)
リリースポイント
import matplotlib.pyplot as plt
def plot_release_point(df, date):
grouped = df.groupby('pitch_type')
colors = {'FF': 'blue', 'SL': 'red', 'FS': 'green', 'ST': 'orange', 'CU': 'purple', 'SI': 'brown'}
for pitch_type, data in grouped:
plt.scatter(data['release_pos_x'], data['release_pos_z'], label=pitch_type, color=colors[pitch_type])
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0)
plt.xlabel('Release Pos X')
plt.ylabel('Release Pos Z')
plt.grid(which='both', linestyle='--', color='gray', alpha=0.5)
plt.title(f'Release Point for {date}')
plt.xlim(-3, -1)
plt.ylim(4.5, 6.5)
plt.show()
df_2023_04_01 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-01']
df_2023_04_08 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-08']
df_2023_04_15 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-15']
plot_release_point(df_2023_04_01, '2023-04-01')
plot_release_point(df_2023_04_08, '2023-04-08')
plot_release_point(df_2023_04_15, '2023-04-15')
リリースポイント(球種ごと)
import matplotlib.pyplot as plt
def plot_release_point_by_date(df_1, df_2, df_3):
combined_df = pd.concat([df_1, df_2, df_3])
grouped = combined_df.groupby('pitch_type')
nrows = 3
ncols = 2
titles = []
fig, axes = plt.subplots(nrows=nrows, ncols=ncols, figsize=(10, 15))
for idx, (pitch_type, data) in enumerate(grouped):
titles.append(pitch_type)
row = idx // ncols
col = idx % ncols
ax = axes[row][col]
data_1 = data[data.index.isin(df_1.index)]
data_2 = data[data.index.isin(df_2.index)]
data_3 = data[data.index.isin(df_3.index)]
ax.scatter(data_1['release_pos_x'], data_1['release_pos_z'], label='2023-04-01', color='blue')
ax.scatter(data_2['release_pos_x'], data_2['release_pos_z'], label='2023-04-08', color='red')
ax.scatter(data_3['release_pos_x'], data_3['release_pos_z'], label='2023-04-15', color='green')
ax.set_title(pitch_type)
ax.set_xlabel('Release Pos X')
ax.set_ylabel('Release Pos Z')
ax.grid(which='both', linestyle='--', color='gray', alpha=0.5)
ax.legend()
# Set the limits for X and Y axes
ax.set_xlim(-3, -1)
ax.set_ylim(4.5, 6.5)
plt.tight_layout()
plt.show()
df_2023_04_01 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-01']
df_2023_04_08 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-08']
df_2023_04_15 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-15']
plot_release_point_by_date(df_2023_04_01, df_2023_04_08, df_2023_04_15)
スピンレート(球種ごと) / Boxplot
import matplotlib.pyplot as plt
import pandas as pd
def plot_spin_rate_by_date_boxplot(df_1, df_2, df_3, pitch_types, dates):
pitch_types = [pt for pt in pitch_types if pt is not None and pd.notna(pt)] # nan を除外
fig, axs = plt.subplots(len(pitch_types), 1, figsize=(8, len(pitch_types) * 4))
for i, pitch_type in enumerate(pitch_types):
ax = axs[i]
grouped_1 = df_1[df_1['pitch_type'] == pitch_type].dropna(subset=['release_spin_rate'])
grouped_2 = df_2[df_2['pitch_type'] == pitch_type].dropna(subset=['release_spin_rate'])
grouped_3 = df_3[df_3['pitch_type'] == pitch_type].dropna(subset=['release_spin_rate'])
data_to_plot = []
labels = []
if not grouped_1.empty:
data_to_plot.append(grouped_1['release_spin_rate'])
labels.append(dates[0])
if not grouped_2.empty:
data_to_plot.append(grouped_2['release_spin_rate'])
labels.append(dates[1])
if not grouped_3.empty:
data_to_plot.append(grouped_3['release_spin_rate'])
labels.append(dates[2])
if data_to_plot:
bp = ax.boxplot(data_to_plot, labels=labels)
for j, d in enumerate(data_to_plot):
mean_val = d.mean()
ax.text(j + 0.8, mean_val, f"{mean_val:.1f}", ha='center', va='bottom', fontsize=10, color='blue')
ax.set_title(f"Pitch Type: {pitch_type}")
ax.set_xlabel('Date')
ax.set_ylabel('Release Spin Rate')
# 罫線
ax.grid(which='both', linestyle='--', color='gray', alpha=0.5)
fig.suptitle('Release Spin Rate by Date and Pitch Type', fontsize=16, y=1.02)
plt.tight_layout(pad=3)
plt.show()
pitch_types_1 = df_2023_04_01['pitch_type'].unique()
pitch_types_2 = df_2023_04_08['pitch_type'].unique()
pitch_types_3 = df_2023_04_15['pitch_type'].unique()
# すべての日に存在する球種を取得
all_pitch_types = set(pitch_types_1) | set(pitch_types_2) | set(pitch_types_3)
dates = ["2023-04-01", "2023-04-08", "2023-04-15"]
plot_spin_rate_by_date_boxplot(df_2023_04_01, df_2023_04_08, df_2023_04_15, all_pitch_types, dates)
スピード(球種ごと) / Boxplot
def plot_release_speed_by_date_boxplot(df_1, df_2, df_3, pitch_types, dates):
pitch_types = [pt for pt in pitch_types if pt is not None and pd.notna(pt)] # nan を除外
fig, axs = plt.subplots(len(pitch_types), 1, figsize=(8, len(pitch_types) * 4))
for i, pitch_type in enumerate(pitch_types):
ax = axs[i]
grouped_1 = df_1[df_1['pitch_type'] == pitch_type].dropna(subset=['release_speed'])
grouped_2 = df_2[df_2['pitch_type'] == pitch_type].dropna(subset=['release_speed'])
grouped_3 = df_3[df_3['pitch_type'] == pitch_type].dropna(subset=['release_speed'])
data_to_plot = []
labels = []
if not grouped_1.empty:
data_to_plot.append(grouped_1['release_speed'])
labels.append(dates[0])
if not grouped_2.empty:
data_to_plot.append(grouped_2['release_speed'])
labels.append(dates[1])
if not grouped_3.empty:
data_to_plot.append(grouped_3['release_speed'])
labels.append(dates[2])
if data_to_plot:
bp = ax.boxplot(data_to_plot, labels=labels)
for j, d in enumerate(data_to_plot):
mean_val = d.mean()
ax.text(j + 0.8, mean_val, f"{mean_val:.1f}", ha='center', va='bottom', fontsize=10, color='blue')
ax.set_title(f"Pitch Type: {pitch_type}")
ax.set_xlabel('Date')
ax.set_ylabel('Release Speed')
# 罫線
ax.grid(which='both', linestyle='--', color='gray', alpha=0.5)
fig.suptitle('Release Speed by Date and Pitch Type', fontsize=16, y=1.02)
plt.tight_layout(pad=3)
plt.show()
# 2023年4月1日、4月8日、4月15日のデータに対してリリーススピードをプロット
dates = ['2023-04-01', '2023-04-08', '2023-04-15']
plot_release_speed_by_date_boxplot(df_2023_04_01, df_2023_04_08, df_2023_04_15, all_pitch_types, dates)
スピード(球種ごと) / Boxplot ※kmへ換算
def plot_release_speed_by_date_boxplot_km(df_1, df_2, df_3, pitch_types, dates):
pitch_types = [pt for pt in pitch_types if pt is not None and pd.notna(pt)] # nan を除外
fig, axs = plt.subplots(len(pitch_types), 1, figsize=(8, len(pitch_types) * 4))
for i, pitch_type in enumerate(pitch_types):
ax = axs[i]
grouped_1 = df_1[df_1['pitch_type'] == pitch_type].dropna(subset=['release_speed'])
grouped_2 = df_2[df_2['pitch_type'] == pitch_type].dropna(subset=['release_speed'])
grouped_3 = df_3[df_3['pitch_type'] == pitch_type].dropna(subset=['release_speed'])
data_to_plot = []
labels = []
if not grouped_1.empty:
data_to_plot.append(grouped_1['release_speed'] * 1.60934)
labels.append(dates[0])
if not grouped_2.empty:
data_to_plot.append(grouped_2['release_speed'] * 1.60934)
labels.append(dates[1])
if not grouped_3.empty:
data_to_plot.append(grouped_3['release_speed'] * 1.60934)
labels.append(dates[2])
if data_to_plot:
bp = ax.boxplot(data_to_plot, labels=labels)
for j, d in enumerate(data_to_plot):
mean_val = d.mean()
ax.text(j + 0.8, mean_val, f"{mean_val:.1f}", ha='center', va='bottom', fontsize=10, color='blue')
ax.set_title(f"Pitch Type: {pitch_type}")
ax.set_xlabel('Date')
ax.set_ylabel('Release Speed (km/h)')
# 罫線
ax.grid(which='both', linestyle='--', color='gray', alpha=0.5)
fig.suptitle('Release Speed by Date and Pitch Type (km/h)', fontsize=16, y=1.02)
plt.tight_layout(pad=3)
plt.show()
# 2023年4月1日、4月8日、4月15日のデータに対してリリーススピードをキロメートル単位でプロット
dates = ['2023-04-01', '2023-04-08', '2023-04-15']
plot_release_speed_by_date_boxplot_km(df_2023_04_01, df_2023_04_08, df_2023_04_15, all_pitch_types, dates)
リリースポイント ~ ホーム距離 (球種ごと) / Boxplot
def plot_release_extension_by_date_boxplot(df_1, df_2, df_3, pitch_types, dates):
pitch_types = [pt for pt in pitch_types if pt is not None and pd.notna(pt)] # nan を除外
fig, axs = plt.subplots(len(pitch_types), 1, figsize=(8, len(pitch_types) * 4))
for i, pitch_type in enumerate(pitch_types):
ax = axs[i]
grouped_1 = df_1[df_1['pitch_type'] == pitch_type].dropna(subset=['release_extension'])
grouped_2 = df_2[df_2['pitch_type'] == pitch_type].dropna(subset=['release_extension'])
grouped_3 = df_3[df_3['pitch_type'] == pitch_type].dropna(subset=['release_extension'])
data_to_plot = []
labels = []
if not grouped_1.empty:
data_to_plot.append(grouped_1['release_extension'])
labels.append(dates[0])
if not grouped_2.empty:
data_to_plot.append(grouped_2['release_extension'])
labels.append(dates[1])
if not grouped_3.empty:
data_to_plot.append(grouped_3['release_extension'])
labels.append(dates[2])
if data_to_plot:
bp = ax.boxplot(data_to_plot, labels=labels)
for j, d in enumerate(data_to_plot):
mean_val = d.mean()
ax.text(j + 0.8, mean_val, f"{mean_val:.1f}", ha='center', va='bottom', fontsize=10, color='blue')
ax.set_title(f"Pitch Type: {pitch_type}")
ax.set_xlabel('Date')
ax.set_ylabel('Release Extension (ft)')
# 罫線
ax.grid(which='both', linestyle='--', color='gray', alpha=0.5)
fig.suptitle('Release Extension by Date and Pitch Type (ft)', fontsize=16, y=1.02)
plt.tight_layout(pad=3)
plt.show()
# 2023年4月1日、4月8日、4月15日のデータに対してリリースエクステンションをプロット
dates = ['2023-04-01', '2023-04-08', '2023-04-15']
plot_release_extension_by_date_boxplot(df_2023_04_01, df_2023_04_08, df_2023_04_15, all_pitch_types, dates)
対戦打者・結果
# 2023年4月15日のデータをフィルタリング
df_660261_2023_04_15 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-15']
# 必要な列を選択
df_660261_2023_04_15_results = df_660261_2023_04_15[['batter', 'events', 'des']]
# 2023年4月15日のデータをフィルタリング
df_660261_2023_04_15 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-15']
# events列がNaNでない行をフィルタリング
df_660261_2023_04_15_results_filtered = df_660261_2023_04_15_results.dropna(subset=['events'])
# 結果を表示
print(df_660261_2023_04_15_results_filtered)
結果
batter events des
134 596129 walk Daniel Vogelbach walks.
140 592192 home_run Mark Canha homers (2) on a fly ball to left fi...
144 643446 field_out Jeff McNeil grounds out, first baseman Jesus A...
147 624413 field_out Pete Alonso grounds out, shortstop Aledmys Dia...
148 596019 field_out Francisco Lindor grounds out, second baseman T...
154 516782 hit_by_pitch Starling Marte hit by pitch.
156 607043 field_out Brandon Nimmo lines out sharply to right field...
159 682626 strikeout Francisco Alvarez strikes out on a foul tip.
164 641645 walk Luis Guillorme walks.
168 596129 field_out Daniel Vogelbach grounds out, third baseman Ja...
172 592192 field_out Mark Canha flies out sharply to center fielder...
175 643446 field_out Jeff McNeil grounds out to first baseman Jesus...
178 624413 home_run Pete Alonso homers (7) on a fly ball to left f...
180 596019 field_out Francisco Lindor grounds out, second baseman T...
186 516782 field_out Starling Marte flies out sharply to center fie...
190 607043 single Brandon Nimmo singles on a line drive to right...
195 682626 field_out Francisco Alvarez flies out to second baseman ...
196 641645 strikeout Luis Guillorme strikes out swinging.
201 596129 field_out Daniel Vogelbach grounds out, first baseman Je...
204 592192 strikeout Mark Canha strikes out swinging.
209 643446 field_out Jeff McNeil flies out to center fielder Esteur...
211 624413 strikeout Pete Alonso strikes out swinging.
214 596019 double Francisco Lindor doubles (6) on a ground ball ...
218 516782 field_out Starling Marte flies out to left fielder Conne...
220 607043 strikeout Brandon Nimmo strikes out swinging.
対戦打者・結果(並び替え)
# 2023年4月15日のデータをフィルタリング
df_660261_2023_04_15 = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-15']
# 必要な列を選択
df_660261_2023_04_15_results = df_660261_2023_04_15[['batter', 'events', 'des', 'at_bat_number']]
# events列がNaNでない行をフィルタリング
df_660261_2023_04_15_results_filtered = df_660261_2023_04_15_results.dropna(subset=['events'])
# at_bat_number 列を使って df_660261_2023_04_15_results_filtered をソート
df_660261_2023_04_15_results_filtered_sorted = df_660261_2023_04_15_results_filtered.sort_values(by='at_bat_number')
# 結果を表示
print(df_660261_2023_04_15_results_filtered_sorted)
結果
batter events des \
220 607043 strikeout Brandon Nimmo strikes out swinging.
218 516782 field_out Starling Marte flies out to left fielder Conne...
214 596019 double Francisco Lindor doubles (6) on a ground ball ...
211 624413 strikeout Pete Alonso strikes out swinging.
209 643446 field_out Jeff McNeil flies out to center fielder Esteur...
204 592192 strikeout Mark Canha strikes out swinging.
201 596129 field_out Daniel Vogelbach grounds out, first baseman Je...
196 641645 strikeout Luis Guillorme strikes out swinging.
195 682626 field_out Francisco Alvarez flies out to second baseman ...
190 607043 single Brandon Nimmo singles on a line drive to right...
186 516782 field_out Starling Marte flies out sharply to center fie...
180 596019 field_out Francisco Lindor grounds out, second baseman T...
178 624413 home_run Pete Alonso homers (7) on a fly ball to left f...
175 643446 field_out Jeff McNeil grounds out to first baseman Jesus...
172 592192 field_out Mark Canha flies out sharply to center fielder...
168 596129 field_out Daniel Vogelbach grounds out, third baseman Ja...
164 641645 walk Luis Guillorme walks.
159 682626 strikeout Francisco Alvarez strikes out on a foul tip.
156 607043 field_out Brandon Nimmo lines out sharply to right field...
154 516782 hit_by_pitch Starling Marte hit by pitch.
148 596019 field_out Francisco Lindor grounds out, second baseman T...
147 624413 field_out Pete Alonso grounds out, shortstop Aledmys Dia...
144 643446 field_out Jeff McNeil grounds out, first baseman Jesus A...
140 592192 home_run Mark Canha homers (2) on a fly ball to left fi...
134 596129 walk Daniel Vogelbach walks.
各打者との対戦結果
import matplotlib.pyplot as plt
# 2023年4月15日のデータをフィルタリング
df_660261_fujinami = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-15']
unique_batters = sorted(df_660261_fujinami['at_bat_number'].unique())
nrows = (len(unique_batters) + 1) // 2
ncols = 2
fig, axs = plt.subplots(nrows, ncols, figsize=(12, nrows * 6), sharex=True, sharey=True)
x = [-0.88, 0.88, 0.88, -0.88, -0.88]
y = [1.51, 1.51, 3.4, 3.4, 1.51]
# at_bat_number でグループ化
grouped_by_batter = df_660261_fujinami.groupby('at_bat_number')
# グラフのタイトル用に結果データを取得
results_data = df_660261_2023_04_15_results_filtered_sorted
# unique_batters を at_bat_number で並べ替え
unique_batters = sorted(unique_batters, key=lambda x: grouped_by_batter.get_group(x).iloc[0]['at_bat_number'])
for i, batter in enumerate(unique_batters):
data_by_batter = grouped_by_batter.get_group(batter)
ax = axs[i // ncols, i % ncols]
ax.fill(x, y, color='r', alpha=0.1)
grouped_by_pitch_type = data_by_batter.groupby('pitch_type')
for pitch_type, data in grouped_by_pitch_type:
ax.scatter(data['plate_x'], data['plate_z'], label=pitch_type, s=200)
hit_data = data[data['events'].isin(['single', 'double', 'triple', 'home_run'])]
if not hit_data.empty:
ax.scatter(hit_data['plate_x'], hit_data['plate_z'], marker='x', s=100, label=f'Hit ({pitch_type})')
for idx, row in data.iterrows():
ax.text(row['plate_x'], row['plate_z'], f"{row['pitch_number']}", fontsize=12, ha='center', va='center', color='white')
last_pitch_result = results_data.iloc[i]['events']
ax.set_title(f'Batter {i+1} (Last Pitch: {last_pitch_result})')
ax.set_xlim(-3, 3)
ax.set_ylim(-2, 6)
ax.set_xlabel('Plate X')
ax.set_ylabel('Plate Z')
ax.legend()
ax.grid(which='both', linestyle='--', color='gray', alpha=0.5)
plt.tight_layout()
plt.show()
各打者との対戦結果(題名に対戦ID)
import matplotlib.pyplot as plt
# 2023年4月15日のデータをフィルタリング
df_660261_fujinami = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-15']
unique_batters = sorted(df_660261_fujinami['at_bat_number'].unique())
nrows = (len(unique_batters) + 1) // 2
ncols = 2
fig, axs = plt.subplots(nrows, ncols, figsize=(12, nrows * 6), sharex=True, sharey=True)
x = [-0.88, 0.88, 0.88, -0.88, -0.88]
y = [1.51, 1.51, 3.4, 3.4, 1.51]
# at_bat_number でグループ化
grouped_by_batter = df_660261_fujinami.groupby('at_bat_number')
# グラフのタイトル用に結果データを取得
results_data = df_660261_2023_04_15_results_filtered_sorted[['batter', 'events', 'des']]
# unique_batters を at_bat_number で並べ替え
unique_batters = sorted(unique_batters, key=lambda x: grouped_by_batter.get_group(x).iloc[0]['at_bat_number'])
for i, batter in enumerate(unique_batters):
data_by_batter = grouped_by_batter.get_group(batter)
ax = axs[i // ncols, i % ncols]
ax.fill(x, y, color='r', alpha=0.1)
grouped_by_pitch_type = data_by_batter.groupby('pitch_type')
for pitch_type, data in grouped_by_pitch_type:
ax.scatter(data['plate_x'], data['plate_z'], label=pitch_type, s=200)
hit_data = data[data['events'].isin(['single', 'double', 'triple', 'home_run'])]
if not hit_data.empty:
ax.scatter(hit_data['plate_x'], hit_data['plate_z'], marker='x', s=100, label=f'Hit ({pitch_type})')
for idx, row in data.iterrows():
ax.text(row['plate_x'], row['plate_z'], f"{row['pitch_number']}", fontsize=12, ha='center', va='center', color='white')
last_pitch_result = results_data.iloc[i]['events']
# タイトルに表示する打者IDを取得
batter_id = results_data.iloc[i]['batter']
# イニングとアウトカウントを取得
inning = data_by_batter.iloc[0]['inning']
outs_when_up = data_by_batter.iloc[0]['outs_when_up']
# タイトルを設定
ax.set_title(f'Batter {batter_id}: Inning {inning}, Outs {outs_when_up} - {last_pitch_result}')
ax.set_xlim(-3, 3)
ax.set_ylim(-2, 6)
ax.set_xlabel('Plate X')
ax.set_ylabel('Plate Z')
ax.legend()
ax.grid(which='both', linestyle='--', color='gray', alpha=0.5)
plt.tight_layout()
plt.show()
各打者との対戦結果 / 文章
des_list = df_660261_2023_04_15_results_filtered_sorted['des'].tolist()
for des in des_list:
print(des)
結果
Brandon Nimmo strikes out swinging.
Starling Marte flies out to left fielder Conner Capel.
Francisco Lindor doubles (6) on a ground ball to right fielder Ramon Laureano.
Pete Alonso strikes out swinging.
Jeff McNeil flies out to center fielder Esteury Ruiz.
Mark Canha strikes out swinging.
Daniel Vogelbach grounds out, first baseman Jesus Aguilar to pitcher Shintaro Fujinami.
Luis Guillorme strikes out swinging.
Francisco Alvarez flies out to second baseman Tony Kemp.
Brandon Nimmo singles on a line drive to right fielder Ramon Laureano.
Starling Marte flies out sharply to center fielder Esteury Ruiz.
Francisco Lindor grounds out, second baseman Tony Kemp to first baseman Jesus Aguilar.
Pete Alonso homers (7) on a fly ball to left field.
Jeff McNeil grounds out to first baseman Jesus Aguilar.
Mark Canha flies out sharply to center fielder Esteury Ruiz.
Daniel Vogelbach grounds out, third baseman Jace Peterson to first baseman Jesus Aguilar.
Luis Guillorme walks.
Francisco Alvarez strikes out on a foul tip.
Brandon Nimmo lines out sharply to right fielder Ramon Laureano.
Starling Marte hit by pitch.
Francisco Lindor grounds out, second baseman Tony Kemp to first baseman Jesus Aguilar. Starling Marte to 3rd.
Pete Alonso grounds out, shortstop Aledmys Diaz to first baseman Jesus Aguilar.
Jeff McNeil grounds out, first baseman Jesus Aguilar to pitcher Shintaro Fujinami.
Mark Canha homers (2) on a fly ball to left field.
Daniel Vogelbach walks.
各打者との対戦結果 / 文章 ※並び替え
des_list = df_660261_2023_04_15_results_filtered_sorted['des'].tolist()
for i, des in enumerate(des_list, 1):
print(f"{i}. {des}")
結果
1. Brandon Nimmo strikes out swinging.
2. Starling Marte flies out to left fielder Conner Capel.
3. Francisco Lindor doubles (6) on a ground ball to right fielder Ramon Laureano.
4. Pete Alonso strikes out swinging.
5. Jeff McNeil flies out to center fielder Esteury Ruiz.
6. Mark Canha strikes out swinging.
7. Daniel Vogelbach grounds out, first baseman Jesus Aguilar to pitcher Shintaro Fujinami.
8. Luis Guillorme strikes out swinging.
9. Francisco Alvarez flies out to second baseman Tony Kemp.
10. Brandon Nimmo singles on a line drive to right fielder Ramon Laureano.
11. Starling Marte flies out sharply to center fielder Esteury Ruiz.
12. Francisco Lindor grounds out, second baseman Tony Kemp to first baseman Jesus Aguilar.
13. Pete Alonso homers (7) on a fly ball to left field.
14. Jeff McNeil grounds out to first baseman Jesus Aguilar.
15. Mark Canha flies out sharply to center fielder Esteury Ruiz.
16. Daniel Vogelbach grounds out, third baseman Jace Peterson to first baseman Jesus Aguilar.
17. Luis Guillorme walks.
18. Francisco Alvarez strikes out on a foul tip.
19. Brandon Nimmo lines out sharply to right fielder Ramon Laureano.
20. Starling Marte hit by pitch.
21. Francisco Lindor grounds out, second baseman Tony Kemp to first baseman Jesus Aguilar. Starling Marte to 3rd.
22. Pete Alonso grounds out, shortstop Aledmys Diaz to first baseman Jesus Aguilar.
23. Jeff McNeil grounds out, first baseman Jesus Aguilar to pitcher Shintaro Fujinami.
24. Mark Canha homers (2) on a fly ball to left field.
25. Daniel Vogelbach walks.
- ブランドン・ニモが空振り三振。
- スターリング・マルテが左翼手コナー・ケーペルへのフライアウト。
- フランシスコ・リンドーアがライトフィールダー・ラモン・ローレアノへのグラウンドボールで二塁打(6)。
- ピート・アロンソが空振り三振。
- ジェフ・マクニールが中堅手エステュリ・ルイスへのフライアウト。
- マーク・カナが空振り三振。
- ダニエル・ヴォーゲルバックが一塁手ジーザス・アギラーから投手藤浪晋太郎へのゴロアウト。
- ルイス・ギリオルメが空振り三振。
- フランシスコ・アルバレスが二塁手トニー・ケンプへのフライアウト。
- ブランドン・ニモがライトフィールダー・ラモン・ローレアノへのライナーシングル。
- スターリング・マルテが中堅手エステュリ・ルイスへの鋭いフライアウト。
- フランシスコ・リンドーアが二塁手トニー・ケンプから一塁手ジーザス・アギラーへのゴロアウト。
- ピート・アロンソが左翼への本塁打(7)。
- ジェフ・マクニールが一塁手ジーザス・アギラーへのゴロアウト。
- マーク・カナが中堅手エステュリ・ルイスへの鋭いフライアウト。
- ダニエル・ヴォーゲルバックが三塁手ジェイス・ピーターソンから一塁手ジーザス・アギラーへのゴロアウト。
- ルイス・ギリオルメが四球。
- フランシスコ・アルバレスがファウルチップで三振。
- ブランドン・ニモがライトフィールダー・ラモン・ローレアノへの鋭いライナーアウト。
- スターリング・マルテが死球。
- フランシスコ・リンドーアが二塁手トニー・ケンプから一塁手ジーザス・アギラーへのゴロアウト。スターリング・マルテが3塁へ進む。
- ピート・アロンソが遊撃手アレドミス・ディアスから一塁手ジーザス・アギラーへのゴロアウト。
- ジェフ・マクニールが一塁手ジーザス・アギラーから投手藤浪晋太郎へのゴロアウト。
- マーク・カナが左翼への本塁打(2)。
- ダニエル・ヴォーゲルバックが四球。
対戦打者ID
# 2023年4月15日のデータをフィルタリング
df_660261_fujinami = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-15']
unique_batters = sorted(df_660261_fujinami['at_bat_number'].unique())
# at_bat_number でグループ化
grouped_by_batter = df_660261_fujinami.groupby('at_bat_number')
# グラフのタイトル用に結果データを取得
results_data = df_660261_2023_04_15_results_filtered_sorted[['batter', 'events', 'des']]
# unique_batters を at_bat_number で並べ替え
unique_batters = sorted(unique_batters, key=lambda x: grouped_by_batter.get_group(x).iloc[0]['at_bat_number'])
# バッターIDを格納するリスト
batter_ids = []
# 各バッターのIDをリストに追加
for i, batter in enumerate(unique_batters):
batter_id = results_data.iloc[i]['batter']
batter_ids.append(batter_id)
print(batter_ids)
結果
[607043, 516782, 596019, 624413, 643446, 592192, 596129, 641645, 682626, 607043, 516782, 596019, 624413, 643446, 592192, 596129, 641645, 682626, 607043, 516782, 596019, 624413, 643446, 592192, 596129]
対戦打者ID - 名前の紐づけ
from pybaseball import playerid_reverse_lookup
# バッターIDのリスト
batter_ids = [607043, 516782, 596019, 624413, 643446, 592192, 596129, 641645, 682626, 607043, 516782, 596019, 624413, 643446, 592192, 596129, 641645, 682626, 607043, 516782, 596019, 624413, 643446, 592192, 596129]
# 重複を削除する
unique_batter_ids = list(set(batter_ids))
# バッターIDと名前の対応関係を格納する辞書
batter_names = {}
# IDごとに選手名を検索
for batter_id in unique_batter_ids:
player_info = playerid_reverse_lookup([batter_id], key_type='mlbam')
batter_name = player_info['name_first'].iloc[0] + ' ' + player_info['name_last'].iloc[0]
batter_names[batter_id] = batter_name
# バッターIDと名前の対応関係を表示
for batter_id, batter_name in batter_names.items():
print(f'{batter_id}: {batter_name}')
結果
Gathering player lookup table. This may take a moment.
592192: mark canha
596129: dan vogelbach
682626: francisco álvarez
607043: brandon nimmo
641645: luis guillorme
516782: starling marte
596019: francisco lindor
643446: jeff mcneil
624413: pete alonso
各対戦打者との結果 (題名に名前入り)
import matplotlib.pyplot as plt
# ID と選手名のマッピング
id_to_name_mapping = {
592192: "Mark Canha",
596129: "Dan Vogelbach",
682626: "Francisco Álvarez",
607043: "Brandon Nimmo",
641645: "Luis Guillorme",
516782: "Starling Marte",
596019: "Francisco Lindor",
643446: "Jeff McNeil",
624413: "Pete Alonso"
}
# 2023年4月15日のデータをフィルタリング
df_660261_fujinami = df_660261_all_dates[df_660261_all_dates['game_date'] == '2023-04-15']
unique_batters = sorted(df_660261_fujinami['at_bat_number'].unique())
nrows = (len(unique_batters) + 1) // 2
ncols = 2
fig, axs = plt.subplots(nrows, ncols, figsize=(12, nrows * 6), sharex=True, sharey=True)
x = [-0.88, 0.88, 0.88, -0.88, -0.88]
y = [1.51, 1.51, 3.4, 3.4, 1.51]
# at_bat_number でグループ化
grouped_by_batter = df_660261_fujinami.groupby('at_bat_number')
# グラフのタイトル用に結果データを取得
results_data = df_660261_2023_04_15_results_filtered_sorted[['batter', 'events', 'des']]
# unique_batters を at_bat_number で並べ替え
unique_batters = sorted(unique_batters, key=lambda x: grouped_by_batter.get_group(x).iloc[0]['at_bat_number'])
for i, batter in enumerate(unique_batters):
data_by_batter = grouped_by_batter.get_group(batter)
ax = axs[i // ncols, i % ncols]
ax.fill(x, y, color='r', alpha=0.1)
grouped_by_pitch_type = data_by_batter.groupby('pitch_type')
for pitch_type, data in grouped_by_pitch_type:
ax.scatter(data['plate_x'], data['plate_z'], label=pitch_type, s=200)
hit_data = data[data['events'].isin(['single', 'double', 'triple', 'home_run'])]
if not hit_data.empty:
ax.scatter(hit_data['plate_x'], hit_data['plate_z'], marker='x', s=100, label=f'Hit ({pitch_type})')
for idx, row in data.iterrows():
ax.text(row['plate_x'], row['plate_z'], f"{row['pitch_number']}", fontsize=12, ha='center', va='center', color='white')
last_pitch_result = results_data.iloc[i]['events']
# タイトルに表示する打者名を取得
batter_id = results_data.iloc[i]['batter']
batter_name = id_to_name_mapping[batter_id]
# イニングとアウトカウントを取得
inning = data_by_batter.iloc[0]['inning']
outs_when_up = data_by_batter.iloc[0]['outs_when_up']
# タイトルを設定
ax.set_title(f'{batter_name} : Inning {inning}, Outs {outs_when_up} - {last_pitch_result}')
ax.set_xlim(-3, 3)
ax.set_ylim(-2, 6)
ax.set_xlabel('Plate X')
ax.set_ylabel('Plate Z')
ax.legend()
ax.grid(which='both', linestyle='--', color='gray', alpha=0.5)
plt.tight_layout()
plt.show()
以上