2

I'm trying to combine 3 datasets in one plot. Each dataset has it's own y and x error. I'm receiving this error message:

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

when I run this code:

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()

Could it be that list slicing isn't working in this case? All the x values and y values are in one list each (x_val_all, y_val_all respectively) and so are the corresponding errors.

Sample code to reproduce:

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()
7
  • Can you post the full stacktrace? It helps narrow down where the error is occuring. Commented Nov 17, 2018 at 9:01
  • @AndrewGuy, sure just edited the question above. Commented Nov 17, 2018 at 9:04
  • Works fine for me using some dummy data. I'm running Python 3.6 though. Commented Nov 17, 2018 at 10:13
  • 1
    Can you post a fully reproducible example? i.e. include some dummy data etc. That way someone can just copy and paste to try it out. I'm wondering if you've got a typo somewhere. Commented Nov 17, 2018 at 10:19
  • 1
    x_err has two elements, so you cannot index it with numbers like 7, 8 or 15. Commented Nov 17, 2018 at 10:55

2 Answers 2

1

Indexing x_err is the root cause of your error, as this is a list of two elements. My personal preference to fix this would be to use a list comprehension:

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()

(Note the use of _x within the list comprehension - list comprehension leaks into the local scope in Python 2.7, which would overwrite the earlier x variable if we used x as the variable within the comprehension.)

You could also do:

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")

although this is a little more verbose.

Sign up to request clarification or add additional context in comments.

7 Comments

I see! is this the only way to handle varying asymmetric errors or is there a better way than constructing something like: x_err=[x_low,x_upr]
It doesn't seem an unreasonable way of doing it. I would just use list comprehension when trying to subscript these asymmetric errors.
your first suggestion (My personal preference...etc) isn't plotting the data correctly but the second one after that one does.
Ok, that's a bit odd - all 3 examples work the same in my environment. That could be a python version issue.
A general remark: Consider using numpy arrays instead of lists of lists.
|
1

Have a look at the docs you are presenting the x_error wrong, the list needs to be 2x7 however the way you slice it does does not produce that result. You are slicing a len 2 list with range 7. The code below gives you the plot you want

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])

enter image description here

Edit: for errors like this I recommend using numpy as its array allow you to easily check dimension and index into them easier than lists of lists.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.