Python绘制非对称上下限误差棒结果异常如何修正
我使用自有数据测试误差棒绘制时得到了异常结果。
我有原始DataFrame dotvalue 如下:
ticker AAPL AMD BIDU GOOGL IXIC MSFT NDXT NVDA NXPI QCOM SWKS TXN 5 0.222649 3.512100e-02 0.043558 0.153921 0.374783 0.201710 0.377886 0.159817 0.206961 0.151937 0.132801 0.226767 10 0.203363 3.398862e-02 0.113287 0.173990 0.393209 0.236895 0.421558 0.205209 0.326829 0.128487 0.174043 0.312648 ... 145 0.089661 4.591069e-05 0.136814 0.017958 0.030406 0.000834 0.083278 0.162984 0.081382 0.081221 0.047221 0.057464 150 0.143404 2.403103e-02 0.076241 0.113305 0.061792 0.014000 0.096749 0.060709 0.170400 0.341342 0.049486 0.059982
对应的点图如下:
对x轴每个取值,我计算了序列 avg=dotvalue.mean(axis=1),结果如下:
5 0.190659 10 0.226959 ... 145 0.065772 150 0.100953
将avg序列添加到图中效果如下:
之后我按如下方式计算置信区间:
ci_u = dotvalue.quantile(q=0.975, axis=1) # upper limit ci_l = dotvalue.quantile(q=0.025, axis=1) # lower limit
ci_u的结果示例:
5 0.377033 10 0.413762 ... 145 0.155787 150 0.294333
ci_l的结果示例:
5 0.037441 10 0.055796 ... 145 0.000263 150 0.016758
我希望x轴每个点的误差棒以上述ci_u为上限、ci_l为下限,围绕avg值绘制。我尝试调用 avg.plot(yerr = (ci_l, ci_u), ls = '-', marker = 'o', figsize = (10,5), label = "average") 得到的结果如下:
这个结果明显错误,比如x=5时,误差棒上下限本应为0.037441和0.377033,但图中对应误差棒范围大概是(0.15, 0.57)。请问是什么原因导致该问题,应该如何修正?
问题原因
pandas的plot方法中yerr参数接收的不是误差棒的绝对上下限值,而是相对于平均值的上下偏移量。你直接传入ci_l和ci_u的绝对值,会导致误差范围完全错位:比如x=5时平均值是0.190659,传入的下限0.037441会被当成向下偏移0.037441,实际渲染下限就是0.190659 - 0.037441 ≈ 0.15,上限就是0.190659 + 0.377033 ≈ 0.57,和你看到的错误结果完全匹配。
修正方案
你只需要先计算上下限和平均值的偏差,再传入yerr即可:
# 计算上下偏差量 yerr_l = avg - ci_l yerr_u = ci_u - avg # 传入偏差量绘制 avg.plot(yerr=(yerr_l, yerr_u), ls='-', marker='o', figsize=(10,5), label="average")
如果需要更灵活的控制,也可以改用matplotlib原生的errorbar方法实现:
import matplotlib.pyplot as plt plt.figure(figsize=(10,5)) plt.errorbar(x=avg.index, y=avg.values, yerr=[yerr_l.values, yerr_u.values], fmt='-o', label='average') plt.legend() plt.show()
内容的提问来源于stack exchange,提问作者Lazer

