Tag Archive
amateur astronomy awk bash b[e] supergiant cartoon conference convert evolved star exoplanet fedora figaro fits fun galaxy iraf large magellanic cloud latex linux lmc machine learning magellanic clouds massive star matplotlib meteor mypaper paper peblo photometry planet pro-am pyraf python red supergiant scisoft skinakas observatory small magellanic cloud smc spectroscopy starlink talk ubuntu university of crete video x-ray yellow hypergiant
matplotlib: missed errorbars in logarithmic plot
While manipulating some data I came across to, what looked, a strange behavior with the errorbar of matplotlib, when plotting the results from linear to logarithmic scale.
Suppose these data:
import matplotlib.pyplot as plt
import numpy as np
s=[19.0, 20.0, 21.0, 22.0, 24.0]
v=[36.5, 66.814250000000001, 130.17750000000001, 498.57466666666664, 19.41]
verr=[0.28999999999999998, 80.075044597909169, 71.322124839818571, 650.11015891565125, 0.02]
plt.errorbar(s,v,yerr=verr)
plt.show()
and the result looked like this:
where the errorbars are obviously visible, but when I switched to the logarithmic scale, by using:
plt.yscale('log')
plt.show()
then the result was this:
where some errorbars are not visible (although their caps are still visible). So, what is going on?
I couldn’t figure out what was the problem, so I asked at StackOverflow. I got an answer by “Dan”, in which he pointed to the fact that some of the errors were (that large) that led to negative values (not valid for log). That’s why they were not displayed. The solution was to use asymmetric errors, by substituting basically the negative error values with a value close to 0 (actually the plotted value, but slightly over 0).
The piece of code that corrected the display is:
import matplotlib.pyplot as plt
import numpy as np
s=[19.0, 20.0, 21.0, 22.0, 24.0]
v=np.array([36.5, 66.814250000000001, 130.17750000000001, 498.57466666666664, 19.41])
verr=np.array([0.28999999999999998, 80.075044597909169, 71.322124839818571, 650.11015891565125, 0.02])
verr2 = np.array(verr)
verr2[np.where(v-verr<=.0)] = v[np.where(v-verr<=.0)]*.999999
plt.errorbar(s,v,yerr=[verr2,verr])
plt.ylim(1E1,1E4)
plt.yscale('log')
plt.show()
with the final output (by adjusting also the axes):