如何调整Matplotlib堆叠柱状图中误差棒的位置?
堆叠柱状图误差棒位置修正方案
问题
在Matplotlib中绘制堆叠柱状图时,为每个堆叠切片添加误差棒后,误差棒全部聚集在图表底部,无法对应到各自的堆叠切片位置。
示例数据
import pandas as pd import numpy as np import matplotlib.pyplot as plt data = { 'class': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C'], 1: [0.329705, 0.671022, 0.668366, 0.065326, 0.169130, 0.211676, 0.064732, 0.927455, 0.203308, 0.002299, 0.322461, 0.092376], 2: [0.582468, 0.969697, 0.729358, 0.565941, 0.886812, 0.246542, 0.272845, 0.267764, 0.218754, 0.296160, 0.289441, 0.491691], 3: [0.760131, 0.175007, 0.625848, 0.544123, 0.199601, 0.804688, 0.019928, 0.863459, 0.173769, 0.379593, 0.137946, 0.534573], 4: [0.240984, 0.564373, 0.810989, 0.554100, 0.151519, 0.237268, 0.991679, 0.899854, 0.998449, 0.896210, 0.698002, 0.695594], 5: [0.768396, 0.937719, 0.634198, 0.551964, 0.895280, 0.988008, 0.783552, 0.098560, 0.921954, 0.007269, 0.040120, 0.364231], 6: [0.469820, 0.570865, 0.559299, 0.024383, 0.985258, 0.580174, 0.371842, 0.143537, 0.162110, 0.452698, 0.354060, 0.853589], 7: [0.368209, 0.673083, 0.555111, 0.520188, 0.612360, 0.957880, 0.806270, 0.763971, 0.330368, 0.210543, 0.401879, 0.952164], 8: [0.099985, 0.727631, 0.723997, 0.401070, 0.684621, 0.699878, 0.595760, 0.945066, 0.485593, 0.213349, 0.751918, 0.180683] } df = pd.DataFrame(data) df_grouped = df.groupby('class')
原问题代码
fig, ax = plt.subplots() for i,col in enumerate(df_grouped.mean().columns): ax.bar(df_grouped.mean().index, height=df_grouped.mean()[col], bottom=df_grouped.mean().iloc[:,:i].sum(axis=1), width=0.85) ax.errorbar(df_grouped.mean().index, df_grouped.mean()[col], yerr=df_grouped.std()[col], fmt='none', ecolor='black', capsize=3, capthick=2)
修正方案
误差棒位置错误的核心原因是:仅使用当前切片的均值作为y轴坐标,未叠加之前所有堆叠切片的高度总和(即bar函数中的bottom值)。需要将误差棒的y轴位置调整为当前切片的底部位置加上切片高度的一半,使其对齐到切片中心。
修正后代码:
fig, ax = plt.subplots(figsize=(10, 6)) # 提前计算均值和标准差,避免重复计算 mean_df = df_grouped.mean() std_df = df_grouped.std() for i, col in enumerate(mean_df.columns): # 计算当前切片的底部偏移量(之前所有切片的均值总和) bottom = mean_df.iloc[:, :i].sum(axis=1) # 绘制堆叠柱形 ax.bar(mean_df.index, mean_df[col], bottom=bottom, width=0.85, label=f'列 {col}') # 计算误差棒的中心位置:底部偏移 + 当前切片高度的一半 err_center_y = bottom + mean_df[col] / 2 # 添加误差棒 ax.errorbar(mean_df.index, err_center_y, yerr=std_df[col], fmt='none', ecolor='black', capsize=3, capthick=1) # 添加图例并调整布局 ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left') plt.tight_layout() plt.show()
关键说明
- 提前计算
mean_df和std_df,减少重复计算,提升代码效率 - 误差棒的
y参数使用bottom + mean_df[col]/2,确保误差棒位于对应堆叠切片的中心位置 - 保留原有的误差棒样式参数,仅调整位置
内容的提问来源于stack exchange,提问作者yhgsag
相关产品推荐
相关产品推荐

