「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」。
前言
用Python和Matplotlib绘制一个足球运动员的数据可视化图表
让我们愉快地开始吧~
开发工具
Python版本: 3.6.4
相关模块:
requests模块;
pandas模块;
matplotlib模块;
numpy模块;
以及一些Python自带的模块。
环境搭建
安装Python并添加到环境变量,pip安装需要的相关模块即可。
数据来源于下面两个网站,Understat和Fbref
欧洲足球五大联赛,英超、意甲、西甲、德甲、法甲。
先看一下射门数据的可视化,本质上和篮球的出手点图差不多,都是散点图类型。
从Understat网站爬取射门数据,使用BeautifulSoup、JSON和pandas解析和处理数据
# 请求数据, C罗的ID为2371
url = 'https://understat.com/player/2371'
html = requests.get(url)
# 解析处理数据
parse_soup = soup(html.content, 'lxml')
scripts = parse_soup.find_all('script')
strings = scripts[3].string
ind_start = strings.index("('")+2
ind_end = strings.index("')")
json_data = strings[ind_start:ind_end]
json_data = json_data.encode('utf8').decode('unicode_escape')
data = json.loads(json_data)
print(data)
# 处理数据, 包含射门位置、预期进球、射门结果、赛季
x = []
y = []
xg = []
result = []
season = []
for i, _ in enumerate(data):
for key in data[i]:
if key == 'X':
x.append(data[i][key])
if key == 'Y':
y.append(data[i][key])
if key == 'xG':
xg.append(data[i][key])
if key == 'result':
result.append(data[i][key])
if key == 'season':
season.append(data[i][key])
columns = ['X', 'Y', 'xG', 'Result', 'Season']
df_understat = pd.DataFrame([x, y, xg, result, season], index=columns)
df_understat = df_understat.T
df_understat = df_understat.apply(pd.to_numeric, errors='ignore')
# 得到最终的结果
print(df_understat)
此处的ID,通过查询球员名字可知
查询中国球员武磊,点击访问,在地址栏处,可以看到球员ID
得到数据
包含射门位置(x、y)、xG(预期进球)、射门结果、赛季。
其中x、y的坐标值为0~1之间,不适合在Matplotlib显示,所以选择放大100倍
df_understat['X'] = df_understat['X'].apply(lambda x: x*100)
df_understat['Y'] = df_understat['Y'].apply(lambda x: x*100)
print(df_understat)
得到结果
既然已经成功获取Understat网站的数据,就可以去获取Fbref网站的数据啦。
这里是球员的一些个人信息,以及赛季的平均数据
比如全名、国家、位置、俱乐部、联赛、年龄、出生年份、上场时间、得分数据等等。
因为网页的数据是表格形式,所以直接使用pandas的read_html函数,解析表格爬取数据。
这个网站需要取消一下证书验证,要不然连接不成功
# 全局取消证书验证
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
获取球员的相关数据
def readfromhtml(filepath):
# 选择第二个表格
df = pd.read_html(filepath)[0]
column_lst = list(df.columns)
for index in range(len(column_lst)):
column_lst[index] = column_lst[index][1]
df.columns = column_lst
df.drop(df[df['Player'] == 'Player'].index, inplace=True)
df = df.fillna('0')
df.set_index('Rk', drop=True, inplace=True)
try:
df['Comp'] = df['Comp'].apply(lambda x: ' '.join(x.split()[1:]))
df['Nation'] = df['Nation'].astype(str)
df['Nation'] = df['Nation'].apply(lambda x: x.split()[-1])
except:
print('Error in uploading file:' + filepath)
finally:
df = df.apply(pd.to_numeric, errors='ignore')
return df
# 获取2020-2021欧洲五大联赛球员数据
df_fbref = readfromhtml('https://fbref.com/en/comps/Big5/shooting/players/Big-5-European-Leagues-Stats')
print(df_fbref)
得到结果
数据都已经准备好了,那么我们就可以将数据绘制到图表
# 安装
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple mplsoccer
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple highlight_text
安装mplsoccer、highlight_text这两个Python库
初始化一些设置,画布背景色、字体颜色、默认字体,字体大小,此处选择中文字体
from highlight_text import ax_text,fig_text
import mplsoccer
# 背景色
background = '#D6DBD9'
# 字体颜色
text_color = 'black'
mpl.rcParams['xtick.color'] = text_color
mpl.rcParams['ytick.color'] = text_color
mpl.rcParams['text.color'] = text_color
# 中文字体
mpl.rcParams['font.family'] = 'Songti SC'
mpl.rcParams['legend.fontsize'] = 12