Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing the bottom error caps only on matplotlib

I wanted to display only half error bars, as they are symetric ; as I had no clue how to do this with a "clean way", I chose to use asymetric errors with 0 on the bottom side ; but then, when I displayed caps, I realised this was not the best way to do this.

Here's the code :

  import numpy as np
  import matplotlib.pyplot as plt

  N = 5
  men_means = (20, 35, 30, 35, 27)
  men_std = (2, 3, 4, 1, 2)

  ind = np.arange(N)
  width = 0.35

  fig, ax = plt.subplots()
  rects1 = ax.bar(ind, men_means, width, color='r',yerr=[np.zeros(len(men_std)),men_std],capsize = 5)

  women_means = (25, 32, 34, 20, 25)
  women_std = (3, 5, 2, 3, 3)
  rects2 = ax.bar(ind + width, women_means, width, color='y',yerr=[np.zeros(len(women_std)),women_std],capsize = 5)

  plt.show()

And this is the plot I get :myPlot. As you can see, my way of plotting half error bars is probably not what should be done.

So is there any way to hide the bottom cap line or a better way to plot half error bars ?

like image 301
A.Aussage Avatar asked Jan 30 '23 18:01

A.Aussage


1 Answers

ax.errorbar has the option to set uplims=True or lolims=True to signify that the means repesent the upper or lower limits, respectively. Unfortunately, it doesn't seem like you can use these options directly with ax.bar, so we have to plot the errorbar and the bar plot separately.

The documentation for the uplims/lolims options in ax.errorbar:

lolims / uplims / xlolims / xuplims : bool, optional, default:None

These arguments can be used to indicate that a value gives only upper/lower limits. In that case a caret symbol is used to indicate this. lims-arguments may be of the same type as xerr and yerr. To use limits with inverted axes, set_xlim() or set_ylim() must be called before errorbar().

Note that using this option changes your caps to arrows. See below for an example of how to change them back to caps, if you need flat caps instead of arrows.

You can see these options in action in this example on the matplotlib website.

Now, here's your example, modified:

import numpy as np
import matplotlib.pyplot as plt

N = 5
men_means = (20, 35, 30, 35, 27)
men_std = (2, 3, 4, 1, 2)

ind = np.arange(N)
width = 0.35

fig, ax = plt.subplots()
rects1 = ax.bar(ind, men_means, width, color='r')
err1 = ax.errorbar(ind, men_means, yerr=men_std, lolims=True, capsize = 0, ls='None', color='k')

women_means = (25, 32, 34, 20, 25)
women_std = (3, 5, 2, 3, 3)
rects2 = ax.bar(ind + width, women_means, width, color='y')
err2 = ax.errorbar(ind + width, women_means, yerr=women_std, lolims=True, capsize = 0, ls='None', color='k')

plt.show()

enter image description here

If you don't like the arrows, you change them to flat caps, by changing the marker of the caplines that are returned (as the second item) from ax.errorbar. We can change them from the arrows to the marker style _, and then control their size with .set_markersize:

import numpy as np
import matplotlib.pyplot as plt

N = 5
men_means = (20, 35, 30, 35, 27)
men_std = (2, 3, 4, 1, 2)

ind = np.arange(N)
width = 0.35

fig, ax = plt.subplots()
rects1 = ax.bar(ind, men_means, width, color='r')
plotline1, caplines1, barlinecols1 = ax.errorbar(
        ind, men_means, yerr=men_std, lolims=True,
        capsize = 0, ls='None', color='k')

caplines1[0].set_marker('_')
caplines1[0].set_markersize(20)

women_means = (25, 32, 34, 20, 25)
women_std = (3, 5, 2, 3, 3)
rects2 = ax.bar(ind + width, women_means, width, color='y')
plotline2, caplines2, barlinecols2 = ax.errorbar(
        ind + width, women_means, yerr=women_std,
        lolims=True, capsize = 0, ls='None', color='k')

caplines2[0].set_marker('_')
caplines2[0].set_markersize(10)

plt.show()

enter image description here

like image 153
tmdavison Avatar answered Feb 02 '23 08:02

tmdavison