python - 绘制错误栏时出现奇怪的错误

python - strange error when plotting errorbars

我正在尝试将 3 个数据集合并到一个图中。每个数据集都有自己的 y 和 x 错误。我收到此错误消息:

Traceback (most recent call last):
  File "SED_plot.py", line 310, in <module>
    plt.errorbar(x0, y0, xerr=x0err, linestyle='None', ecolor="black", label= "Channel Width")
  File "/Library/Python/2.7/site-packages/matplotlib-override/matplotlib/pyplot.py", line 2766, in errorbar
    errorevery=errorevery, capthick=capthick, **kwargs)
  File "/Library/Python/2.7/site-packages/matplotlib-override/matplotlib/axes/_axes.py", line 2749, in errorbar
    in cbook.safezip(x, xerr[0])]
  File "/Library/Python/2.7/site-packages/matplotlib-override/matplotlib/cbook.py", line 1479, in safezip
    raise ValueError(_safezip_msg % (Nx, i + 1, len(arg)))
ValueError: In safezip, len(args[0])=16 but len(args[1])=48

当我 运行 此代码时:

x0, y0          = x_val_all[0:16], y_val_all[0:16]
x0err, y0err    = x_error_all[0:16], y_error_all[0:16]
x1, y1          = x_val_all[17:33], y_val_all[17:33]
x1err, y1err    = x_error_all[17:33], y_error_all[17:33]
x2, y2          = x_val_all[33:49], y_val_all[33:49]
x2err, y2err    = x_error_all[33:49], y_error_all[33:49]

plt.errorbar(x0, y0, xerr=x0err, linestyle='None', ecolor="black", label= "Channel Width")
plt.errorbar(x0, y0, yerr=y0err, linestyle='None', ecolor="black", label= "Standard Deviation")
plt.errorbar(x1, y1, xerr=x1err, yerr=y1err, ecolor="red")
plt.errorbar(x2, y2, xerr=x2err, yerr=y2err, ecolor="purple")
plt.show()

会不会是列表切片在这种情况下不起作用?所有的 x 值和 y 值都在一个列表中(分别为 x_val_all、y_val_all),相应的错误也是如此。

要重现的示例代码:

import matplotlib.pyplot as plt

y = range(0,21,1)
x = range(0,21,1)
y_err = [0.5]*21

x_low = [0.7]*21
x_upper = [1.4]*21
x_err = [x_low, x_upper]


plt.errorbar(x[0:7],y[0:7], xerr=x_err[0:7], yerr=y_err[0:7], linestyle="none", color="black")
plt.errorbar(x[8:15],y[8:15], xerr=x_err[8:15], yerr=y_err[8:15], linestyle="none", color="red")

plt.show()

索引 x_err 是错误的根本原因,因为这是一个包含两个元素的列表。我个人更喜欢使用列表理解来解决这个问题:

import matplotlib.pyplot as plt

y = range(0,21,1)
x = range(0,21,1)
y_err = [0.5]*21

x_low = [0.7]*21
x_upper = [1.4]*21
x_err = [x_low, x_upper]

plt.errorbar(x[0:7], y[0:7], xerr=[_x[0:7] for _x in x_err], yerr=y_err[0:7], linestyle="none", color="black")
plt.errorbar(x[8:15], y[8:15], xerr=[_x[8:15] for _x in x_err], yerr=y_err[8:15], linestyle="none", color="red")

plt.show()

(注意在列表推导中使用 _x - 在 Python 2.7 中列表推导会泄漏到本地范围,如果我们使用 x 会覆盖早期的变量 x作为理解中的变量。)

你也可以这样做:

plt.errorbar(x[0:7], y[0:7], xerr=[x_err[0][0:7], x_err[1][0:7]], yerr=y_err[0:7], linestyle="none", color="black")
plt.errorbar(x[8:15], y[8:15], xerr=[x_err[0][8:15], x_err[1][8:15]], yerr=y_err[8:15], linestyle="none", color="red")

虽然这有点冗长。

看看 docs 你呈现的 x_error 是错误的,列表需要是 2x7 但是你切片的方式不会产生那个结果。您正在对范围为 7 的 len 2 列表进行切片。下面的代码为您提供了您想要的情节

import matplotlib.pyplot as plt
y = range(0,21,1)
x = range(0,21,1)
y_err = [0.5]*21

x_low = [0.7]*21
x_upper = [1.4]*21
x_err = [x_low, x_upper]

fig, ax = plt.subplots()
idx = range(0, 16, 7)
for start, stop in zip(idx[:-1], idx[1:]):
    ax.errorbar(x[start:stop], y[start:stop], y_err[start:stop], \
                [ i[start:stop] for i in x_err])

编辑:对于这样的错误,我建议使用 numpy 作为其数组,与列表的列表相比,它可以让您轻松地检查维度并对其进行索引。