close

WBC出場選手のStatcastデータでスプレーチャートを描く:baseball-field-viz を作った

に公開

はじめに

pybaseballの組み込みspraychart()は便利ですが、ヒートマップを重ねられないという制約があります。

seabornのkdeplothistplotでゾーン別の打球密度を表示したい場合、matplotlibで野球場を手動描画する必要があります。

座標変換と野球場描画を毎回書くのが面倒なので、ライブラリにまとめました。

pip install baseball-field-viz

PyPI: https://pypi.org/project/baseball-field-viz/
GitHub: https://github.com/yasumorishima/baseball-field-viz

baseball-field-viz とは

Statcastデータから野球場スプレーチャートを描くPythonライブラリです。

3つの関数を提供します。

from baseball_field_viz import transform_coords, draw_field, spraychart
関数 説明
transform_coords(df) Statcast hc_x/hc_y → フィート座標変換(ホームプレート原点)
draw_field(ax) matplotlib Axesに野球場を描画
spraychart(ax, df, color_by='events') 上2つを組み合わせた一発生成

使い方

一番シンプルな例

import matplotlib.pyplot as plt
from baseball_field_viz import spraychart

fig, ax = plt.subplots(figsize=(10, 10))
spraychart(ax, df, color_by='events', title='選手名 - 打球分布')
plt.show()

color_by='events' でホームラン=赤、トリプル=橙、ダブル=青、シングル=緑に自動色分けされます。

ヒートマップを重ねる(この方法の最大のメリット)

draw_field(ax) で野球場を描いたあと、seabornのkdeplotをそのまま重ねられます。

import seaborn as sns
from baseball_field_viz import draw_field, transform_coords

df_t = transform_coords(df[df['hc_x'].notna()])

fig, axs = plt.subplots(1, 2, figsize=(16, 8))

draw_field(axs[0])
sns.kdeplot(data=df_t[hits_mask], x='x', y='y',
            ax=axs[0], cmap='Reds', fill=True, alpha=0.6)
axs[0].set_xlim(-350, 350); axs[0].set_ylim(-50, 400)

draw_field(axs[1])
sns.kdeplot(data=df_t[outs_mask], x='x', y='y',
            ax=axs[1], cmap='Blues', fill=True, alpha=0.6)
axs[1].set_xlim(-350, 350); axs[1].set_ylim(-50, 400)

plt.tight_layout()
plt.show()

WBC 2026 出場選手のStatcastデータで試す

WBC 2026出場選手(18カ国)の2024〜2025 MLBレギュラーシーズンStatcastデータを使ったKaggleノートブックを公開しています。WBCの試合データではなく、WBCロスター選手のMLBでの打球データです。

Kaggle Notebook: https://www.kaggle.com/code/yasunorim/mlb-statcast-spray-charts-for-wbc-2026-players

全18カ国のスプレーチャート

draw_field(ax) で野球場を描いたあと、国別にカラーリングして散布図を重ねると、全カ国の打球分布を一枚で確認できます。

上位4カ国の比較(spraychart)

spraychart() を使えば数行で各国のスプレーチャートを生成できます。

top_countries = ['USA', 'Dominican Republic', 'Venezuela', 'Japan']
fig, axs = plt.subplots(2, 2, figsize=(16, 14))

for ax, country in zip(axs.flat, top_countries):
    df_c = df[df['country_name'] == country]
    spraychart(ax, df_c, color_by='events', title=country)

plt.tight_layout()
plt.show()

日本のヒットvsアウト ヒートマップ

打球がどのゾーンに集まりやすいかが、kdeplotで視覚的にわかります。ヒットとアウトを左右で比較することで、どのゾーンで生産的な打球が生まれているかを把握できます。

インストール

pip install baseball-field-viz

依存パッケージ:matplotlib>=3.5 / numpy>=1.21 / pandas>=1.3

v0.2.0 追加機能:ストライクゾーン描画

v0.2.0 では、ストライクゾーン描画に対応しました。

from baseball_field_viz import draw_strike_zone, pitch_zone_chart
関数 説明
draw_strike_zone(ax, sz_top=3.5, sz_bot=1.5) ストライクゾーン矩形を描画(plate_x/plate_z座標系)
pitch_zone_chart(ax, df, color_by='pitch_type') 投球位置プロット + ゾーン自動サイズ

Statcastの sz_top/sz_bot は身長から計算した固定値ではなく、投球ごとにHawk-Eyeで実測した値なので精度が高いです。DataFrameに含まれている場合は平均値を自動で使用します。

from pybaseball import statcast_pitcher
from baseball_field_viz import pitch_zone_chart

df = statcast_pitcher('2025-03-01', '2025-10-31', 592789)  # 山本由伸

fig, ax = plt.subplots(figsize=(6, 6))
pitch_zone_chart(ax, df, color_by='pitch_type', title='Yamamoto 2025')
plt.show()

savant-extrasとの組み合わせ

同じく自作のsavant-extras(バットトラッキングデータ取得ライブラリ)と組み合わせると、データ取得から可視化まで一貫したMLB分析パイプラインが構築できます。

まとめ

pip install baseball-field-viz
  • pybaseballのspraychart()ではできないヒートマップ重ね表示が可能
  • matplotlibのAxesを直接操作できるので、kdeplothistplotなど任意のプロットを重ねられる
  • WBC 2026データで実際に動作確認済み(Kaggle Notebookで公開中)

PyPI: https://pypi.org/project/baseball-field-viz/
GitHub: https://github.com/yasumorishima/baseball-field-viz

GitHubで編集を提案

Discussion

Image