iT邦幫忙

2023 iThome 鐵人賽

DAY 25
0

說到數據分析,就也會提到數據視覺化,pybaseball 也有提供一些 functions 可以呈現數據圖表,方便大家在做分析報告的時候可以有更好的視覺效果,今天就來介紹有哪些圖表可以用。

matplotlib

在介紹 pybaseball 裡的 functions 前,想先介紹 matplotlib 這個套件,是很多人在使用 python 時,做資料視覺化常用的工具。pybaseball 裡的 plotting 也有運用這個套件來呈現棒球數據。裡面用到的工具如下:

  • axes:設定座標軸的類別,可以自己設定 X 軸與 Y 軸的比例,也可以定義刻度的精細程度。
  • patches:用來快速的繪製幾何圖形,像是這次就會用到:PathPatch (曲線)、Polygon 多邊形和 Rectangle (長方形) 等。
  • offsetbox:可以創造出一個放置圖片的 offsetbox,pybaseball 使用的 AnnotationBbox 會根據提供的座標移動的相對應的位置,會依照 axes 的設定有大小變化,
  • path:用來畫各式各樣的線,甚至能把照片轉換成線後再做其他客製化。
  • pyplot:最後用來畫圖的工具,除了畫圖也能提供文字 title,跟註解的 legend

plot_stadium

繪製各球隊的球場,有五個參數可以使用:

  • team:查詢的球隊,需填入正確的球隊名稱不然會回傳錯誤,可以參考 官方文件 提供的球隊名稱。必填。
  • title:顯示在圖片最上方的標題,預設會是各球場的球場名。
  • width:圖片寬度,預設會是五吋。
  • height:圖片高度,預設也會是五吋。
  • axis:自定義的座標軸。

範例:

from pybaseball import plot_stadium

# 紅襪主場球場芬威球場
plot_stadium("red_sox")

# 更改標題為 My Stadium
plot_stadium("red_sox", title="My Stadium")

# 把長寬各改成 100 pixel
plot_stadium("red_sox", width=100, height=100)

結果:

spraychart

有了球場圖,就可以再來用 spraychart 這個 function 來製作出打者在各球場的打擊分布圖,這張圖會需要知道打者的各個擊球落點,所以會需要使用 statcast_batter 來獲得打者資料。statcast_batter 的詳細資訊可以參考我之前的:

Day 11 - Statcast 打擊篇 - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天 (ithome.com.tw)

會有九個參數可以使用:

  • data:必填,需為 Pandas DataFrame,並且是 statcast 的打者數據,也必須根據目標球場去做主場篩選,不然會因為打者在不同球場的分布而有落差 (大聯盟球場有些差異很大)。
  • team_stadium:球場的主場隊伍,一樣填入跟 plot_stadium 一樣的隊伍名稱。
  • title:圖片的標題,預設是空字串,不能填中文。
  • tooltips:目前已停用,不然可以把滑鼠移到落點並獲得追加的資訊。
  • size:打擊落點的大小,預設是 100。
  • colorby:落點顏色的指標,也就是說會根據這個提供的值去把落點做分類跟分顏色,例如預設是 events,就會根據各落點的結果 (像是安打或是飛球出局等) 去分類與顏色。
  • legend_title:註記的標題,預設會是 colorby 的分類類別名稱。
  • width:圖片寬度,預設是 500。
  • height:圖片高度,預設是 500。

範例:

from pybaseball import statcast_batter, spraychart

# 獲得張育成 2023 的打擊數據
data = statcast_batter('2023-03-31', '2023-12-01', 644374)

# 篩選他在紅襪主場的資料
sub_data = data[data['home_team'] == 'BOS']

# 製作張育成在芬威球場的打擊分布圖
spraychart(sub_data, 'red_sox', title='2023 Yu Chang Spray Chart')

結果:

也可用球員來分類比較:

from pybaseball import statcast_batter, spraychart
import pandas as pd

# 獲得張育成 2023 的打擊數據
chang_data = statcast_batter('2023-03-31', '2023-12-01', 644374)

# 獲得金河成 2023 的打擊數據
kim_data = statcast_batter('2023-03-31', '2023-12-01', 673490)

# 合併兩個人的打擊數據
data = pd.concat([chang_data, kim_data])

# 製作他們兩個在釀酒人主場的打擊落點
home_data = data[data['home_team'] == 'MIL']
spraychart(home_data, 'brewers', title='Chang vs Kim', colorby='player')

結果:

plot_bb_profile

根據 Statcast 資料裡的 bb_type 也就是擊球種類 (滾地、平飛、飛球與內飛) 來繪製長條分布圖,有兩個參數可以使用:

  • df:Statcast functions 回傳的 DataFrame,必填。
  • parameter:顯示長條圖的指標,預設是 launch_angle。指標裡的數值需為數字不然會有錯誤。

目前 官方文件 提供的範例會有錯誤,資料會需要多做處理:

# 官方文件的範例
from pybaseball.plotting import plot_bb_profile
from pybaseball import statcast
import matplotlib.pyplot as plt

# 獲得 2018 5/1 - 5/4 所有場次的 Statcast 資料
df = statcast("2018-05-01","2018-05-04")

# 如果直接使用這行畫圖會出現 boolean value of NA is ambiguous 的錯誤
# plot_bb_profile(df, parameter="launch_angle")

# 需確定目標的指標沒有 NA 值,因為有時候有 bb_type 指標也可能會有 NA 值造成錯誤
df = df.dropna(subset="launch_angle")
plot_bb_profile(df, parameter="launch_angle")
plt.show()

結果:

X 軸會是打擊仰角,Y 軸會是數量,可惜他們這個圖沒提供 legend 讓使用者知道哪個顏色是代表哪個種類,依我自己對打擊仰角的理解由左至右應該是 滾地、平飛、飛球與內飛。

plot_team

使用 FanGraphs 的資料獲得各球隊在選取指標的分布圖,會需要使用者選取兩個指標分別代表 X 軸與 Y 軸,會有四個參數可供使用:

  • data:每年度的 FanGraphs 資料,必填。
  • x_axis:代表 X 軸的數據指標,如果不是在 FanGraphs 裡的欄位會回傳錯誤。
  • y_axis:代表 X 軸的數據指標,如果不是在 FanGraphs 裡的欄位會回傳錯誤。
  • title:圖片的標題。

範例:

from pybaseball import plot_teams, team_batting

# 獲得 2023 FanGraphs 的隊伍打擊資料
data = team_batting(2023)

# 製作各球隊 OPS 與 LD 的關係圖
plot_teams(data, "OPS", "LD")

結果:

官方的範例有使用各球隊的 Logo 代表他們,但不知道為什麼我使用的時候沒有顯示。可能之後我會再開個 Issue 問問。

plot_strike_zone

運用 Statcast 資料顯示投手投出的球在好球帶的相對位置,可以根據提供的種類而有不同的顏色分類,有六個參數可以使用:

  • data:Statcast 回傳資料,必填。
  • title:圖片標題,預設是空字串。
  • colorby:投球位置顏色的指標,也就是說會根據這個提供的值去把投球位置做分類跟分顏色,例如預設是 pitch_type (球種),就會根據各球的投球結果 (像是球種或是球速) 去分類與顏色。
  • legend_title:註記的標題,預設會是 colorby 的分類類別名稱。
  • annotation:球裡顯示的資訊,預設是球種 pitch_type
  • axis:好球帶的座標。

範例:

from pybaseball.plotting import plot_strike_zone
from pybaseball import statcast_pitcher

# 獲得達比修有在 2023/4/16 12K 的比賽投球資料
data = statcast_pitcher('2023-04-16', '2023-04-16', 506433)

# 製作投球位置與球種分類圖
plot_strike_zone(data, title = "Darvish 2023/04/16 12 SO Game")

結果:

我們也可以使用各球的結果來分類,然後球上面顯示球速:

# 根據投球結果分類並在球上面顯示出手球速
plot_strike_zone(data, title = "Darvish 2023/04/16 12 SO Game", colorby='description', annotation="release_speed")

結果:

本日小結

今天整理了所有 pybaseball 的畫圖 functions,謝謝大家耐心地看完。數據視覺化是一項在數據分析裡很重要的技能,要怎麼製作這些圖並且能解釋圖的功用是很值得大家思考的。

介紹完 Plotting,明天再來介紹棒球公開資料庫 Lahman

今天的程式碼:
https://colab.research.google.com/drive/1he3K76Jbq0qe7AyY-1SbtLPFO-Hl4rAu?usp=sharing


上一篇
Day 24 - Amateur Draft
下一篇
Day 26 - Lahman
系列文
Python 棒球數據分析套件 pybaseball 介紹30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言