Pascal
Pascal

Reputation: 70

How I can adjust properly the error bar in matplotlib?

I need to fix an errorbar like in the graph, but I don't know how to use it. I get an error, and it doesn't work. Please can you help me?

#! /usr/bin/python3
# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

x = np.arange(9)
country = [
    "Finland",
    "Denmark",
    "Switzerland",
    "Iceland",
    "Netherland",
    "Norway",
    "Sweden",
    "Luxembourg"
]
data = {
    "Explained by : Log GDP per Capita": [1.446, 1.502, 1.566, 1.482, 1.501, 1.543, 1.478, 1.751],
    "Explained by : Social Support": [1.106, 1.108, 1.079, 1.172, 1.079, 1.108, 1.062, 1.003],
    "Explained by : Healthy life expectancy": [0.741, 0.763, 0.816, 0.772, 0.753, 0.782, 0.763, 0.760],
    "Explained by : Freedom to make life choices": [0.691, 0.686, 0.653, 0.698, 0.647, 0.703, 0.685, 0.639],
    "Explained by : Generosity": [0.124, 0.208, 0.204, 0.293, 0.302, 0.249, 0.244, 0.166],
    "Explained by : Perceptions of corruption": [0.481, 0.485, 0.413, 0.170, 0.384, 0.427, 0.448, 0.353],
    "Dystopia + residual": [3.253, 2.868, 2.839, 2.967, 2.798, 2.580, 2.683, 2.653]
}
error_value = [[7.904, 7.780], [7.687, 7.552], [7.643, 7.500], [7.670, 7.438], [7.518, 7.410], [7.462, 7.323], [7.433, 7.293], [7.396, 7.252]]

df = pd.DataFrame(data, index=country)

df.plot(width=0.1, kind='barh', stacked=True, figsize=(11, 8))
plt.subplots_adjust(bottom=0.2)
# plt.errorbar(country, error_value, yerr=error_value)
plt.axvline(x=2.43, label="Dystopia (hapiness=2.43)")

plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),
           fancybox=True, shadow=True, ncol=3)
plt.xticks(x)
plt.show()

![Capture d’écran du 2022-02-25 11-06-56.png

Upvotes: 1

Views: 323

Answers (1)

Mr. T
Mr. T

Reputation: 12410

Error bars are drawn as differences from the center. You provide seemingly the values where each error bar ends, so you have to recalculate the distance to the endpoint and provide a numpy array in form (2, N) where the first row contains the negative errorbar values and the second row the positive values:

...
df.plot(width=0.1, kind='barh', stacked=True, figsize=(11, 8))
#determine x-values of the stacked bars
country_sum = df.sum(axis=1).values
#calculate differences of error bar values to bar heights 
#and transform array into necessary (2, N) form
err_vals = np.abs(np.asarray(error_value).T - country_sum[None])[::-1, :]
plt.errorbar(country_sum, np.arange(df.shape[0]), xerr=err_vals, capsize=4, color="k", ls="none")
plt.subplots_adjust(bottom=0.2)
...

Sample output:

enter image description here

Upvotes: 1

Related Questions