You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何可视化三层嵌套字典存储的NHL射门命中率数据?

NHL射门命中率随类型与距离的可视化实现方法

步骤1:将嵌套字典转换为结构化DataFrame

三层嵌套字典的结构不利于直接绘图,先把它展开成包含距离区间、射门类型、命中率的二维DataFrame:

import pandas as pd

# 假设你的嵌套字典名为shot_stats
flat_data = []
for distance_range, stat_group in shot_stats.items():
    # 提取命中率数据(统计类型为Percentage的部分)
    for shot_type, hit_rate in stat_group['Percentage'].items():
        flat_data.append({
            '距离区间': distance_range,
            '射门类型': shot_type,
            '命中率': hit_rate
        })

# 生成结构化DataFrame
hit_rate_df = pd.DataFrame(flat_data)

步骤2:规范距离区间的排序

默认字符串排序可能导致距离区间顺序混乱(比如"10-20"排在"0-10"前面),可以将其设为有序分类:

# 根据你的实际区间调整顺序
distance_order = ['0-10', '10-20', '20-30', '30-40', '40+']
hit_rate_df['距离区间'] = pd.Categorical(hit_rate_df['距离区间'], categories=distance_order, ordered=True)

步骤3:绘制可视化图表

推荐用seaborn实现分类对比可视化,以下提供两种常用方案:

方案A:分组柱状图(适合对比同一距离下不同射门类型的命中率)

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_style("whitegrid")

# 绘制分组柱状图
plot = sns.catplot(
    data=hit_rate_df,
    x='距离区间',
    y='命中率',
    hue='射门类型',
    kind='bar',
    height=6,
    aspect=1.5
)

# 设置图表标签与标题
plot.set_axis_labels('距球门距离区间(英尺)', '射门命中率')
plot.fig.suptitle('射门命中率随类型与距离的变化', y=1.02)

# 调整图例位置避免遮挡
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')

plt.show()

方案B:折线图(适合观察命中率随距离的变化趋势)

如果更关注同一射门类型在不同距离下的命中率变化,可改用折线图:

plot = sns.catplot(
    data=hit_rate_df,
    x='距离区间',
    y='命中率',
    hue='射门类型',
    kind='line',
    marker='o',  # 添加数据点标记
    height=6,
    aspect=1.5
)

plot.set_axis_labels('距球门距离区间(英尺)', '射门命中率')
plot.fig.suptitle('射门命中率随类型与距离的变化趋势', y=1.02)
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')

plt.show()

额外优化建议

  • 如果命中率为小数格式,可通过plt.gca().set_yticklabels(['{:.1f}%'.format(x*100) for x in plt.gca().get_yticks()])将Y轴转为百分比显示
  • 若射门类型过多导致图例拥挤,可尝试横向柱状图(设置kind='barh')

内容的提问来源于stack exchange,提问作者ShaMan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 22:45:38