サッカーを通じて観戦力と分析力を上げていくブログ

基本的にはサッカー×データに関して試してみたことをまとめています。最近はもっぱらPythonを使った可視化中心。時々自分の好きなガジェットも。

【Python】matplotlibを使って出場時間データをヒットマップで可視化してみる

今回は選手別の出場時間のデータから、Pythonの描画ライブラリmatplotlibを使ってグラフィカルに可視化する方法をまとめておきます。グラフィカルに表示することで、下記の記事見たいなことが感覚的に分かります。

96lovefootball.hatenablog.com

f:id:virgilvd:20190128231959p:plain

▲サッリ監督がいかにスタメンを固定しているかがよく分かります。

データの準備

ヒートマップを作成するに当たって、Whoscored.com等から選手別の出場時間の情報を下記のような形(選手別の出場時間だけが横持ちの状態)で保存しておきます。1試合増えるごとに1行下にデータが増えていくような形です。

f:id:virgilvd:20190203183532p:plain

今回描画したいヒートマップを作る上では、縦に選手名、横に試合情報が並ぶ形の方が都合が良いのですが、個人的にこの方が記録しやすかったのでこう(選手別の出場時間だけが横持ちの状態)しています。

データの整形

今回もPythonの実行環境には「Google Colab」を使います。可視化に向けて、まずはデータの取り込みと整形を行っていきます。下記の図を可視化するためには、行名(index)が選手名、列名(columns)が節となっているDataframeを用意する必要があります。

f:id:virgilvd:20190128230901p:plain

Google Colab」の使い方は下記記事を参考にしていただき、先ほど示したデータを取り込みます。

96lovefootball.hatenablog.com

次に今回の可視化に必要なライブラリを読み込みます。使用するのはPandasとNumpy、そしてmatplotlibとなります。

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

毎度恒例ですが%matplotlib inlineはgoogle colabでグラフを描画するためのおまじない。matplotlibの概略については下記も参考にしてみて下さい。

96lovefootball.hatenablog.com

余計な列を削除して、行列を入れ替える

可視化に必要な列以外を削除します。Dateframeの列の削除は.drop( )を使い、列側の削除であることを示すため引数にaxis=1を指定します。(下記例のdf_lfcは、用意したcsvをDataframeにした物です)

df=df_lfc.drop(['Competition','Date', 'Opponent'], axis=1)

f:id:virgilvd:20190203192530p:plain

次に.set_index( )を使用して、Match Num列をindexに指定します。

df=df.set_index('Match Num')

f:id:virgilvd:20190203194510p:plain

最後に行列を入れ替えます。行列の入れ替えは、.Tとするだけで出来てしまいます。

df=df.T

f:id:virgilvd:20190203194727p:plain

出場時間の多い選手順に並び替える

ここまでで可視化に必要なデータの形にはなっているのですが、可視化により意味を持たせるために選手の並び順を変更しておきます。今回は上から順に出場時間が長くなるように並び替えてみます。

まずは各選手の出場時間の合計値の列を追加します。.sum( )の引数にaxis=1を指定することで列側に合計値を追加することが出来ます。

df['sum']=df.sum(axis=1)

f:id:virgilvd:20190203195240p:plain

追加したsum列を降順にソートし、最後にsum列を削除してあげれば可視化の準備は完了となります。ソートには.sort_values( )を使用し、降順にするために引数にascending=Falseを指定します。列の削除は先ほどと同様.drop( )です。

df=df.sort_values('sum', ascending=False)
df=df.drop(['sum'], axis=1)

f:id:virgilvd:20190203195624p:plain

pcolorを使ってヒートマップを描画

f:id:virgilvd:20190203200046p:plain

fig = plt.figure(figsize=(6, 6))
ax = fig.add_subplot(1,1,1)

ax.pcolor(df, cmap=plt.cm.Reds)

ax.set_xticks(np.arange(df.shape[1])+0.5)
ax.set_yticks(np.arange(df.shape[0])+0.5)

ax.set_xticklabels(df.columns.values)
ax.set_yticklabels(df.index.values)

ax.set_xlabel('Match Week')
ax.set_ylabel('Players Name')

ax.invert_yaxis()

plt.show()

いよいよ可視化の部分です。ヒートマップの表示には、.pcolor( )を使うことで実現できます。第1引数に、先ほど整形したデータを与えてあげるだけで値に応じたヒートマップを自動で作成してくれます。ヒートマップの色に関しては、引数campで指定することが出来ます。(自分はあまり理解していませんが)上記コードのcmap=plt.cm.RedsのRedsの部分を、公式のリファレンスを参考に指定することで変更できます。

f:id:virgilvd:20190203200659p:plain

▲指定出来るカラーの一部。出典:https://matplotlib.org/examples/color/colormaps_reference.html

x軸y軸共に0.5ズラして描画しているのは、pcolor関数が( x , y )の値に対して、xからx+1、yからy+1の領域を塗り潰すためです。何言っているか分からないと思うので、分かりやすく解説してくれているサイトを貼っておきます。

d.hatena.ne.jp

軸の名前に関しては、行名と列名をそのまま使いたいので、それぞれ.index.valuesと.columns.valuesをset_yticklabelsとset_xticklabelsに指定しています。

colorbarを表示する

f:id:virgilvd:20190128230901p:plain

最後にカラーバーを表示する方法を記載して終わりたいと思います。ヒートマップを作成したpcolor関数によって返されるオブジェクトを、colorbarに与えてあげることでカラーバーが表示されるようになります。

im=ax.pcolor(df, cmap=plt.cm.Reds)

fig.colorbar(im)

最初に指定したplt.figure( )の領域内に描画されるため、カラーバーを表示した分元のヒートマップは幅が狭くなります。そのため、あらかじめ広めにfigureを取っておくと良いと思います。

以上、Pythonを使って選手別出場時間データをヒートマップで可視化する方法でした。

戦術や分析に関して、こういう見方もあるよ、こうして見た方がいいよ、などご意見等ありましたら、コメントで教えていただけると幸いです。ぜひよろしくお願いいたします!