如何绘制含多键且各键对应不同值的字典直方图?
解决方案:基于字典数据绘制训练/测试指标对比柱状图
需求回顾
现有两个字典数据
t_onset和t_max,每个字典包含测试(Accuracy/Precision等)和训练(Accuracy Training/Precision Training等)的指标值。需要生成2个图表(每个字典对应一个),每个图表中针对4个指标,分别展示训练与测试数据的柱状对比。
原始字典数据:
t_onset = {'Accuracy': 0.7086659064994298, 'Precision': 0.6666666666666666, 'Recall': 0.00390625, 'F1': 0.007766990291262136, 'Accuracy Training': 0.7086659064994298, 'Precision Training': 0.6666666666666666, 'Recall Training': 0.00390625, 'F1 Training': 0.007766990291262136} t_max = {'Accuracy': 0.7080957810718358, 'Precision': 0.5, 'Recall': 0.00390625, 'F1': 0.007751937984496124, 'Accuracy Training': 0.7080957810718358, 'Precision Training': 0.5, 'Recall Training': 0.00390625, 'F1 Training': 0.007751937984496124}
原代码问题分析
- 需求匹配错误:原代码按指标循环生成4个图,但需求是按字典键生成2个图
- 变量未定义:直接使用
t_onset/t_max但未将原始数据定义为字典变量 - 语法错误:
train_data行缺少闭合括号 - 图表类型误用:
hist()是直方图(用于展示数据分布),此处是单个数值的对比,应使用柱状图bar() - 子图未初始化:未创建
axes子图对象就直接调用
修正后的代码
import matplotlib.pyplot as plt import numpy as np # 1. 定义原始字典数据 t_onset = {'Accuracy': 0.7086659064994298, 'Precision': 0.6666666666666666, 'Recall': 0.00390625, 'F1': 0.007766990291262136, 'Accuracy Training': 0.7086659064994298, 'Precision Training': 0.6666666666666666, 'Recall Training': 0.00390625, 'F1 Training': 0.007766990291262136} t_max = {'Accuracy': 0.7080957810718358, 'Precision': 0.5, 'Recall': 0.00390625, 'F1': 0.007751937984496124, 'Accuracy Training': 0.7080957810718358, 'Precision Training': 0.5, 'Recall Training': 0.00390625, 'F1 Training': 0.007751937984496124} # 2. 配置基础参数 keys = ['t_onset', 't_max'] key_data = [t_onset, t_max] # 对应每个键的字典数据 metrics = ['Accuracy', 'Precision', 'Recall', 'F1'] x = np.arange(len(metrics)) # 指标的x轴位置 width = 0.35 # 柱状图宽度 # 3. 创建2个子图(1行2列) fig, axes = plt.subplots(1, 2, figsize=(12, 5)) # 4. 遍历每个键和对应的子图 for ax, key_name, data_dict in zip(axes, keys, key_data): # 获取训练和测试的指标值 train_vals = [data_dict[f'{m} Training'] for m in metrics] test_vals = [data_dict[m] for m in metrics] # 绘制并列柱状图 rects1 = ax.bar(x - width/2, train_vals, width, label='Training', alpha=0.7) rects2 = ax.bar(x + width/2, test_vals, width, label='Test', alpha=0.7) # 添加标签、标题和图例 ax.set_xlabel('Metrics') ax.set_ylabel('Score') ax.set_title(f'Metric Comparison: {key_name}') ax.set_xticks(x) ax.set_xticklabels(metrics) ax.legend() # 在柱子上标注数值(可选) for rect in rects1 + rects2: height = rect.get_height() ax.annotate(f'{height:.4f}', xy=(rect.get_x() + rect.get_width() / 2, height), xytext=(0, 3), # 3 points vertical offset textcoords="offset points", ha='center', va='bottom') # 调整子图间距 plt.tight_layout() plt.show()
代码说明
- 先将原始数据定义为字典变量,方便后续调用
- 创建1行2列的子图布局,对应两个字典键的图表
- 使用
bar()绘制并列柱状图,通过调整x轴位置实现训练/测试柱子的并列 - 添加数值标注,让指标值更直观
- 调整图表布局,避免标签重叠
内容的提问来源于stack exchange,提问作者spool
相关产品推荐
相关产品推荐

