Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing errorbars when using yscale('log') at matplotlib

In some cases matplotlib shows plot with errorbars errorneously when using logarithmic scale. Suppose these data (within pylab for example):

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]
errorbar(s,v,yerr=verr)

and I get a normal result but when I switch to logarithmic scale:

yscale('log')

I get a plot in which some errorbars are not visible, although you can still see some of the error bar caps. (See below.) Why is this happening, and how can I fix it?

log plot example

like image 500
gmaravel Avatar asked Nov 21 '12 11:11

gmaravel


2 Answers

Switch to logarithmic scale, but with this command:

plt.yscale('log', nonposy='clip')

Analogously, for the x-axis:

plt.xscale('log', nonposx='clip')

Anyway, if you got a dev version of matplotlib in the last half year, you would have this clipping behavior by default, as discussed in Make nonposy='clip' default for log scale y-axes.

like image 195
khyox Avatar answered Oct 23 '22 07:10

khyox


The problem is that for some points v-verr is becoming negative, values <=0 cannot be shown on a logarithmic axis (log(x), x<=0 is undefined) To get around this you can use asymmetric errors and force the resulting values to be above zero for the offending points.

At any point for which errors are bigger than value verr>=v we assign verr=.999v in this case the error bar will go close to zero.

Here is the script

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[verr>=v] = v[verr>=v]*.999999
plt.errorbar(s,v,yerr=[verr2,verr])
plt.ylim(1E1,1E4)
plt.yscale('log')
plt.show()

Here is the result

Logarithmic plot with error bars

like image 36
Dan Avatar answered Oct 23 '22 09:10

Dan