LoginSignup
3
1

More than 3 years have passed since last update.

[matplotlib] Jリーグ2019年の順位表を色々グラフ化してみた ~その1~

Posted at

はじめに

記事の概要

この記事では、Jリーグの2019年の順位表を使って、matplotlibの使い方を学びながら、サッカーにおいて順位と強く相関するものは何なのかを考察していきます。
自分の学習メモ代わりでもあるので、読みにくいかもしれませんがご容赦ください。

目的

・matplotlibの使い方に慣れる。
・DataFrameを扱えるようになる。
・サッカーの順位において、大事な要素を見つける。

コードと解説

前提

  • 開発環境
    • Anaconda
    • Python3
    • Juptyer-notebook

流れ

1. Jリーグのデータサイトの順位表をチェック
2. 2つの表を結合
3. とりあえず勝ち点をプロットしてみる
4. 総得点と総失点の関係をグラフに
5. 勝・分・敗の割合を見てみる
6. 各要素の相関を見てみる

コード

まずjリーグサイトから表を読み込み、整形。

import pandas as pd

url_ranking = 'https://data.j-league.or.jp/SFRT01/?search=search&yearId=2019&yearIdLabel=2019%E5%B9%B4&competitionId=460&competitionIdLabel=%E6%98%8E%E6%B2%BB%E5%AE%89%E7%94%B0%E7%94%9F%E5%91%BD%EF%BC%AA%EF%BC%91%E3%83%AA%E3%83%BC%E3%82%B0&competitionSectionId=0&competitionSectionIdLabel=%E6%9C%80%E6%96%B0%E7%AF%80&homeAwayFlg=3'
j_ranking = pd.read_html(url_ranking)
j_ranking = pd.DataFrame(j_ranking[0])
j_ranking = j_ranking.drop(['グラフ','試合','直近試合の勝敗','Unnamed: 12','Unnamed: 13'], axis=1) #不要なカラムの削除
j_ranking = j_ranking.rename(columns={"チーム":"チーム名"}) #もう一つの表と結合するためカラム名の変更
j_ranking.head()

image.png

j_detail_ranking = 'https://data.j-league.or.jp/SFRT08/search?competitionYearEx=2019&competitionIdEx=1&selectedCompetitionName=%E6%98%8E%E6%B2%BB%E5%AE%89%E7%94%B0%E7%94%9F%E5%91%BD%EF%BC%AA%EF%BC%91%E3%83%AA%E3%83%BC%E3%82%B0&selectedCompetitionYear=2019%E5%B9%B4&competitionYear=2019&competitionId=1'
j_detail_ranking = pd.read_html(j_detail_ranking)
j_detail_ranking = pd.DataFrame(j_detail_ranking[0])
j_detail_ranking = j_detail_ranking.drop(18) #不要な行の削除
j_detail_ranking = j_detail_ranking.drop(['試合','試合時間','Unnamed: 19','退席','得点','失点','1試合平均得点','1試合平均失点'],axis=1) #不要なカラムの削除
j_detail_ranking.head()

image.png

2種類の表を統合します。

j_all_ranking = j_ranking.merge(j_detail_ranking,on = 'チーム名')
j_all_ranking.head()

image.png

まずは順位と勝ち点でグラフ化しています。

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

#日本語フォントに対応
from matplotlib.font_manager import FontProperties
fp = FontProperties(fname=r'C:\WINDOWS\Fonts\meiryob.ttc', size=14)

x = j_all_ranking.loc[:,'順位'].values
y = j_all_ranking.loc[:,'勝点'].values
plt.plot(x,y, 'bo')
plt.xlabel('順位', fontproperties=fp)
plt.ylabel('勝ち点', fontproperties=fp);

image.png
グラフを見ると何となく上位・中位・下位に分かれていますが、全体的に勝ち点の差は小さいです。

次に総失点と総得点で散布図を作ります。

from adjustText import adjust_text #文字の重なりを防ぐ
#総得点VS総失点

plt.figure(figsize=(14, 8))

teams = j_all_ranking.loc[:, 'チーム名'].values
x = j_all_ranking.loc[:, '得点'].values
y = j_all_ranking.loc[:, '失点'].values

plt.scatter(x,y)
plt.title('総得点 VS 総失点',fontproperties=fp)
plt.xlabel('総得点',fontproperties=fp)
plt.ylabel('総失点',fontproperties=fp)
texts = [plt.text(x[i], y[i], team,fontproperties=fp) for i, team in enumerate(teams)]
adjust_text(texts);

image.png
image.png

グラフの右下に行くほど順位が上がっていますね。
点の位置でそのチームの課題も何となく見えてきます。
例えば、ヴィッセル神戸は得点力がありますが、失点もかなり多いです。失点を減らせば、さらなる上位進出の可能性もあります。

次に勝・分・敗の割合をグラフにします。

#勝・引き・負の割合

x = j_all_ranking.loc[:,'順位'].values
y_1 = j_all_ranking.loc[:,'勝'].values
y_2 = j_all_ranking.loc[:,'分'].values
y_3 = j_all_ranking.loc[:,'敗'].values
p1 = plt.bar(x,y_1)
p2 = plt.bar(x,y_2,bottom=y_1)
p3 = plt.bar(x,y_3,bottom=y_1+y_2)
plt.legend((p1[0],p2[0],p3[0]),('Win','Draw','Lose'),);

image.png

次に各要素の相関係数を調べています。

#相関
pd.options.display.float_format = '{:.2f}'.format #有効数字を指定
j_rank_corr = j_all_ranking.corr()
j_rank_corr

image.png

各値を見ると、「勝ち点・勝・得失点」は当然のことながら順位と強く相関していますね。
「得点・失点」では「得点」の方がわずかに相関係数が大きいですね。これが有意な差なのかどうか、仮説検定などをしないと何とも言えませんが、攻撃より守備が大事といえる可能性もりますね。
「シュート数・被シュート数」はあまり順位と相関しないようですね。
※今回は軽くデータに触れることが目的なので、仮説検定などは行っていません。

感想・反省

・基本的な使い方はマスターできたかな。
・使い方自体より、どの要素を抽出するかという方が悩む。
・実際のデータを使うとリアルで楽しい!

参考

Pythonを使って2019年度J1チームデータを可視化してみた
データサイエンスのためのPython入門講座全33回〜目次とまとめ〜

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1