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

Ébe Isaac picture Ébe Isaac · Mar 6, 2017 · Viewed 7.9k times · Source

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

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

Answer

Martin Evans picture Martin Evans · Mar 6, 2017

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.