这个python案例是否分析射门位置分布图?

wen python案例 3

Python数据可视化实战:如何精准分析足球射门位置分布图?(附完整代码)


目录导读

  1. 射门位置分布图的价值:为什么教练和分析师都在用它?
  2. 数据准备:从哪获取高质量射门数据?(xG坐标格式)
  3. Python核心代码拆解:Matplotlib + Pandas 绘制热力图与散点图
  4. 关键交互技巧:如何用颜色/大小映射射门结果(进球/射正/射偏)
  5. 常见陷阱与优化:坐标归一化、球场背景绘制、数据过拟合问题
  6. 问答环节:解决你关于“射门分布图”的3个高频疑问

射门位置分布图的价值
在足球数据分析中,射门位置图能直观回答“球队进攻效率”和“球员射门习惯”两大核心问题,曼城上赛季83%的进球来自禁区内的“小禁区角”区域,而曼联的远射占比高达27%却转化率仅3%,通过Python绘制分布图,你可以快速发现这些规律,不同于传统统计表,热力图能揭示射门密度进球概率之间的空间关联——这正是xG(预期进球)模型的可视化基础。

这个python案例是否分析射门位置分布图?

数据准备
我们使用StatsBomb免费公开数据集(含英超2023-24赛季所有射门事件),每条数据包含:x(0-120像素坐标)、y(0-80)、shot_outcome(Goal/On Target/Off Target/Blocked)、xG值。关键步骤:将坐标转换为标准球场比例(105m×68m),即x_new = x / 120 * 105y_new = y / 80 * 68,否则热力图会失真。

Python核心代码拆解
以下代码绘制“射门密度热力图 + 进球散点叠加”:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from scipy.ndimage import gaussian_filter
# 加载数据
df = pd.read_csv('shots.csv')
df['x_m'] = df['x'] * 105/120
df['y_m'] = df['y'] * 68/80
# 创建2D直方图(网格分辨率10x10)
heatmap, xedges, yedges = np.histogram2d(df['y_m'], df['x_m'], bins=(12, 16), range=[[0,68],[0,105]])
# 高斯平滑消除锯齿
heatmap_smooth = gaussian_filter(heatmap, sigma=1.2)
# 绘制热力图
plt.imshow(heatmap_smooth, extent=[0,105,0,68], origin='lower', cmap='Reds', alpha=0.7, aspect='equal')
# 叠加进球散点(红色圆点,大小映射xG)
goals = df[df['shot_outcome']=='Goal']
plt.scatter(goals['x_m'], goals['y_m'], c='blue', s=goals['xG']*200, alpha=0.8, edgecolors='white')
# 绘制球场轮廓(简易版)
plt.plot([0,105,105,0,0],[0,0,68,68,0], color='black')
plt.plot([52.5,52.5],[0,68], linestyle='--', color='black')
'Premier League 2023/24 射门位置分布图')
plt.xlabel('球场长度 (米)')
plt.ylabel('球场宽度 (米)')
plt.tight_layout()
plt.show()

关键交互技巧

  • 颜色映射:用cmap='coolwarm'区分左右脚射门习惯(左脚用蓝色,右脚用红色)。
  • 尺寸映射s参数绑定xG值——大圆点代表高概率进球机会,教练可快速定位“关键射门区域”。
  • 分组对比:用for循环分别绘制主队/客队子图,或上半场/下半场对比图。

常见陷阱与优化

  • 坐标陷阱:部分公开数据使用x=100,y=100的归一化坐标,需先检查数据范围。
  • 过拟合:网格数太小(如5×5)会丢失细节,太大(如50×50)则产生噪声,推荐网格数= sqrt(n_shots)/2
  • 球场背景:使用mplsoccer库的VerticalPitch()函数直接绘制标准球场,比手绘线条更专业。

问答环节
问1:为什么我的热力图显示射门集中在边路,但实际球队是中路渗透打法?
:这可能是因为你未按“射门结果”过滤,若包含被封堵(Blocked)射门,边路传中造成的“被封堵射门”会占据大量频次,建议根据分析目标筛选shot_outcome:分析“有效进攻”时仅保留射正+进球,分析“压迫强度”时保留所有射门。

问2:是否只能用Matplotlib?Power BI可以做到吗?
Plotly交互式图表更适合网页展示(支持悬停查看球员姓名),Power BI虽能用内置“热图层”实现,但自定义球场背景和xG权重映射较繁琐,Python的mplsoccer库提供一键绘制专业球场,且能无缝衔接机器学习模型(如聚类分析射门区域)。

问3:如何判断两个球员的射门分布是否有显著差异?
:计算每个网格的“射门频率”和“进球转化率”,然后用scipy.stats.chi2_contingency做卡方检验,例如比较哈兰德和萨拉赫:若p值<0.05,则说明二者射门区域选择有统计学差异,可用分面图可视化。


通过上述代码和思考框架,你不仅能复现“射门位置分布图”,还能延伸到“传球网络图”、“防守压迫热区”等分析。数据可视化不是目的,而是发现故事的手段——下一篇文章我们将用K-Means聚类自动划分射门危险区,敬请期待。

抱歉,评论功能暂时关闭!