Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to increase the thickness of error line in a matplotlib bar chart?

Please refer the minimum working example here.

The bar chart is plotted as shown below but I can't find a way to increase the thickness of the error lines. The elinewidth option is not available in ax.bar

> rects1 = ax.bar(..., elinewidth=3)

AttributeError: Unknown property elinewidth

enter image description here

The following links require the use of ax.errorbar()

  • Change errorbar size
  • How to set the line width of error bar caps, in matplotlib?

But is there an option that can be supplied directly to ax.bar()?

like image 741
Ébe Isaac Avatar asked Mar 06 '17 06:03

Ébe Isaac


1 Answers

You can use the error_kw parameters as follows:

error_kw=dict(lw=5, capsize=5, capthick=3)

So in the example, it would be:

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)  # the x locations for the groups
width = 0.35       # the width of the bars

fig, ax = plt.subplots()
rects1 = ax.bar(ind, men_means, width, color='r', yerr=men_std, error_kw=dict(lw=5, capsize=5, capthick=3))

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=women_std, error_kw=dict(lw=5, capsize=5, capthick=3))

# add some text for labels, title and axes ticks
ax.set_ylabel('Scores')
ax.set_title('Scores by group and gender')
ax.set_xticks(ind + width / 2)
ax.set_xticklabels(('G1', 'G2', 'G3', 'G4', 'G5'))

ax.legend((rects1[0], rects2[0]), ('Men', 'Women'))


def autolabel(rects):
    """
    Attach a text label above each bar displaying its height
    """
    for rect in rects:
        height = rect.get_height()
        ax.text(rect.get_x() + rect.get_width() / 2, 
                1.05 * height,
                f'{height:.0f}',
                ha='center', va='bottom')

autolabel(rects1)
autolabel(rects2)

plt.show()

Giving you:

bar with thick err


An improvement to this would be to display the values above each of the error bars. This can be done by first obtaining the error bar heights as follows:

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)  # the x locations for the groups
width = 0.35        # the width of the bars

fig, ax = plt.subplots()
rects1 = ax.bar(ind, men_means, width, color='r', yerr=men_std, error_kw=dict(lw=5, capsize=5, capthick=3))

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=women_std, error_kw=dict(lw=5, capsize=5, capthick=3))

# add some text for labels, title and axes ticks
ax.set_ylabel('Scores')
ax.set_title('Scores by group and gender')
ax.set_xticks(ind + width / 2)
ax.set_xticklabels(('G1', 'G2', 'G3', 'G4', 'G5'))

ax.set_ylim(0, 45)  # Add space for errorbar height
ax.legend((rects1[0], rects2[0]), ('Men', 'Women'))


def autolabel(rects):
    """
    Attach a text label above each bar displaying its height
    """

    data_line, capline, barlinecols = rects.errorbar

    for err_segment, rect in zip(barlinecols[0].get_segments(), rects):
        height = err_segment[1][1]  # Use height of error bar

        ax.text(rect.get_x() + rect.get_width() / 2, 
                1.05 * height,
                f'{height:.0f}',
                ha='center', va='bottom')

autolabel(rects1)
autolabel(rects2)

plt.show()

Giving you:

Text above error barrs

Note: The y axis limit would need to be calculated.

like image 164
Martin Evans Avatar answered Oct 12 '22 09:10

Martin Evans