如何在分组柱状图(grouped bar plot)中添加误差棒
问题描述
我尝试在分组柱状图中添加误差棒,但目前仅能为所有柱子添加一组,希望为每个ATPS分组内不同Time类别的柱子添加对应误差棒。
数据集示例
| ATPS | Time | Mean | Std |
|---|---|---|---|
| A | 0h | 5.2 | 0.3 |
| A | 24h | 6.1 | 0.4 |
| B | 0h | 4.8 | 0.2 |
| B | 24h | 5.5 | 0.3 |
当前绘图代码
import matplotlib.pyplot as plt import numpy as np # 假设数据 ATPS_groups = ['A', 'B'] Time_categories = ['0h', '24h'] means = [[5.2, 6.1], [4.8, 5.5]] stds = [[0.3, 0.4], [0.2, 0.3]] x = np.arange(len(ATPS_groups)) width = 0.35 fig, ax = plt.subplots() rects1 = ax.bar(x - width/2, [m[0] for m in means], width, label='0h') rects2 = ax.bar(x + width/2, [m[1] for m in means], width, label='24h') # 当前错误的误差棒添加方式(仅添加了一组) ax.errorbar(x, [m[0] for m in means], yerr=[s[0] for s in stds], fmt='none', c='black') ax.set_xticks(x) ax.set_xticklabels(ATPS_groups) ax.legend() plt.show()
期望效果
每个ATPS分组内,0h和24h的柱子分别对应各自的误差棒(标注于柱子顶部中心位置)
解决方案
核心是让误差棒的x坐标与对应类别的柱子位置完全对齐,以下是修正后的实现:
Matplotlib原生实现
import matplotlib.pyplot as plt import numpy as np # 数据集 ATPS_groups = ['A', 'B'] Time_categories = ['0h', '24h'] means = [[5.2, 6.1], [4.8, 5.5]] stds = [[0.3, 0.4], [0.2, 0.3]] x = np.arange(len(ATPS_groups)) width = 0.35 fig, ax = plt.subplots() # 绘制两类柱子 rects1 = ax.bar(x - width/2, [m[0] for m in means], width, label='0h') rects2 = ax.bar(x + width/2, [m[1] for m in means], width, label='24h') # 为0h柱子添加对应误差棒,x坐标匹配柱子中心 ax.errorbar(x - width/2, [m[0] for m in means], yerr=[s[0] for s in stds], fmt='none', c='black', capsize=5) # 为24h柱子添加对应误差棒,x坐标匹配柱子中心 ax.errorbar(x + width/2, [m[1] for m in means], yerr=[s[1] for s in stds], fmt='none', c='black', capsize=5) ax.set_xticks(x) ax.set_xticklabels(ATPS_groups) ax.legend() plt.show()
Pandas结合Matplotlib实现
如果用Pandas处理数据集,思路完全一致:
import pandas as pd import matplotlib.pyplot as plt # 构造DataFrame df = pd.DataFrame({ 'ATPS': ['A', 'A', 'B', 'B'], 'Time': ['0h', '24h', '0h', '24h'], 'Mean': [5.2, 6.1, 4.8, 5.5], 'Std': [0.3, 0.4, 0.2, 0.3] }) pivot_df = df.pivot(index='ATPS', columns='Time', values=['Mean', 'Std']) x = np.arange(len(pivot_df.index)) width = 0.35 fig, ax = plt.subplots() rects1 = ax.bar(x - width/2, pivot_df['Mean']['0h'], width, label='0h') rects2 = ax.bar(x + width/2, pivot_df['Mean']['24h'], width, label='24h') # 对应添加误差棒 ax.errorbar(x - width/2, pivot_df['Mean']['0h'], yerr=pivot_df['Std']['0h'], fmt='none', c='black', capsize=5) ax.errorbar(x + width/2, pivot_df['Mean']['24h'], yerr=pivot_df['Std']['24h'], fmt='none', c='black', capsize=5) ax.set_xticks(x) ax.set_xticklabels(pivot_df.index) ax.legend() plt.show()
关键说明
- 分组柱状图中不同Time类别的柱子x坐标为
x ± width/2,误差棒必须使用完全相同的x坐标才能对齐 capsize参数可控制误差棒两端短横线的长度,提升图表可读性
内容的提问来源于stack exchange,提问作者David Moldes
相关产品推荐
相关产品推荐

