如何基于Pandas聚合数据绘制带阴影误差区域的折线图?
正确绘制带阴影误差区域折线图的方法
我明白你的困扰——用pandas的plot(yerr)确实容易出现阴影淡、样式不可控的问题,尤其是数据量不大的时候,阴影效果几乎看不到。咱们换个更可靠的方式,直接用matplotlib的fill_between来手动绘制误差阴影,这样能完全掌控样式,效果也更清晰。
第一步:明确你的DataFrame结构
先确认你的数据是多层列(MultiIndex)结构,列层级为[Measurement, Statistic],索引是Time。你可以用df.columns来查看:
print(df.columns) # 输出应该类似:MultiIndex([('Measurement 1', 'Mean'), # ('Measurement 1', 'Std'), # ('Measurement 2', 'Mean'), # ('Measurement 2', 'Std')], # )
第二步:提取均值和标准差数据
先把每个测量项的均值、标准差单独提取出来,方便后续使用:
# 提取Measurement 1的均值和标准差 meas1_mean = df['Measurement 1']['Mean'] meas1_std = df['Measurement 1']['Std'] # 提取Measurement 2的均值和标准差 meas2_mean = df['Measurement 2']['Mean'] meas2_std = df['Measurement 2']['Std'] # 时间索引作为x轴数据 time_values = df.index
第三步:手动绘制折线和阴影误差带
用matplotlib的plot画均值折线,再用fill_between绘制上下误差的阴影区域,这样可以精准控制颜色、透明度等样式:
from matplotlib import pyplot as plt from matplotlib.ticker import FuncFormatter def seconds_to_minutes(x, pos): minutes = f'{round(x/60, 0)}' return minutes fig, ax = plt.subplots(figsize=(10,6)) # 可以设置图表大小,更清晰 # 绘制Measurement 1的均值线和阴影误差带 line1, = ax.plot(time_values, meas1_mean, label='Mean 1', color='#1f77b4') ax.fill_between(time_values, meas1_mean - meas1_std, meas1_mean + meas1_std, color=line1.get_color(), alpha=0.25, # 这个透明度比0.15更明显,又不会太突兀 label='± Std 1') # 绘制Measurement 2的均值线和阴影误差带 line2, = ax.plot(time_values, meas2_mean, label='Mean 2', color='#ff7f0e') ax.fill_between(time_values, meas2_mean - meas2_std, meas2_mean + meas2_std, color=line2.get_color(), alpha=0.25, label='± Std 2') # 设置图表属性 ax.set(title="A Line Graph with Shaded Error Regions", xlabel="Time (minutes)", ylabel="Measurement Value") formatter = FuncFormatter(seconds_to_minutes) ax.xaxis.set_major_formatter(formatter) ax.grid(alpha=0.3) # 网格透明度调低,不抢主体内容的风头 ax.legend() plt.tight_layout() # 自动调整布局,避免标签被截断 plt.show()
为什么这个方法更好?
- 样式可控:你可以给每个测量项的均值线和阴影设置对应的颜色,阴影的透明度也能调整到合适的程度,不会像原来那样淡到几乎看不见。
- 可靠性高:不管数据量大小,
fill_between都会准确绘制出误差阴影区域,不会因为数据点少而失效。 - 清晰直观:图例可以明确区分均值线和误差带,让图表可读性更强。
内容的提问来源于stack exchange,提问作者LarsaSolidor
相关产品推荐
相关产品推荐

