Python 案例:被射门次数对比可视化
下面用足球比赛数据做一个"被射门次数对比"的案例,适合展示两支球队或多支球队的防守压力。

两支球队被射门次数对比(柱状图)
import matplotlib.pyplot as plt
import numpy as np
# 设置中文字体(Windows)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 模拟数据:某场比赛两队被射门次数
teams = ['主队 A', '客队 B']
shots_conceded = [8, 15] # 被射门次数
shots_on_target = [3, 9] # 被射正次数
x = np.arange(len(teams))
width = 0.35
fig, ax = plt.subplots(figsize=(8, 5))
bars1 = ax.bar(x - width/2, shots_conceded, width,
label='被射门次数', color='#4C72B0')
bars2 = ax.bar(x + width/2, shots_on_target, width,
label='被射正次数', color='#DD8452')
# 在柱子上标注数值
for bar in bars1 + bars2:
height = bar.get_height()
ax.annotate(f'{height}',
xy=(bar.get_x() + bar.get_width()/2, height),
xytext=(0, 3), textcoords='offset points',
ha='center', fontsize=11)
ax.set_ylabel('次数')
ax.set_title('A队 vs B队 —— 被射门次数对比')
ax.set_xticks(x)
ax.set_xticklabels(teams)
ax.legend()
ax.grid(axis='y', linestyle='--', alpha=0.5)
plt.tight_layout()
plt.show()
效果:一眼看出哪队防守压力更大。
多支球队被射门次数对比(横向条形图)
import matplotlib.pyplot as plt
import pandas as pd
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 模拟 5 支球队一个赛季被射门数据
data = {
'球队': ['曼城', '利物浦', '阿森纳', '切尔西', '曼联'],
'被射门次数': [320, 380, 350, 450, 520],
'被射正次数': [95, 120, 110, 150, 180]
}
df = pd.DataFrame(data).sort_values('被射门次数', ascending=True)
fig, ax = plt.subplots(figsize=(9, 6))
y = range(len(df))
ax.barh([i + 0.2 for i in y], df['被射门次数'], height=0.4,
color='#4C72B0', label='被射门次数')
ax.barh([i - 0.2 for i in y], df['被射正次数'], height=0.4,
color='#DD8452', label='被射正次数')
ax.set_yticks(y)
ax.set_yticklabels(df['球队'])
ax.set_xlabel('次数')
ax.set_title('各队赛季被射门次数对比')
ax.legend()
ax.grid(axis='x', linestyle='--', alpha=0.5)
# 标注数值
for i, (a, b) in enumerate(zip(df['被射门次数'], df['被射正次数'])):
ax.text(a + 5, i + 0.2, str(a), va='center', fontsize=10)
ax.text(b + 5, i - 0.2, str(b), va='center', fontsize=10)
plt.tight_layout()
plt.show()
被射门次数趋势对比(折线图)
如果你想看赛季各轮次的变化趋势:
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
rounds = np.arange(1, 11)
team_a = [6, 8, 5, 7, 10, 9, 11, 8, 6, 7]
team_b = [12, 9, 14, 11, 15, 13, 10, 16, 12, 14]
plt.figure(figsize=(9, 5))
plt.plot(rounds, team_a, marker='o', label='A队被射门次数', color='#4C72B0')
plt.plot(rounds, team_b, marker='s', label='B队被射门次数', color='#DD8452')
plt.fill_between(rounds, team_a, alpha=0.15, color='#4C72B0')
plt.fill_between(rounds, team_b, alpha=0.15, color='#DD8452')
plt.xlabel('联赛轮次')
plt.ylabel('被射门次数')'A队 vs B队 被射门次数趋势对比')
plt.xticks(rounds)
plt.legend()
plt.grid(linestyle='--', alpha=0.5)
plt.tight_layout()
plt.show()
数据来源建议
如果你要用真实数据:
- 足球:Opta、FBref、SofaScore、懂球帝/虎扑 API
- 篮球:NBA Stats API(被投篮次数
opponent FGA) - 自己采集:爬取赛后技术统计页
# 用 pandas 读取 Excel 数据示例
import pandas as pd
df = pd.read_excel('比赛数据.xlsx')
print(df[['球队', '被射门次数', '被射正次数']])
关键要点
| 需求 | 推荐图表 |
|---|---|
| 2 支球队对比 | 分组柱状图 |
| 多支球队排名 | 横向条形图 |
| 时间趋势 | 折线图 |
| 占比关系 | 堆积柱状图 / 饼图 |
需要我帮你改成真实数据接口版本,还是做成篮球(被投篮次数)或 Excel 读取版?告诉我你的具体场景即可 👍