Stacked bar chart with Python
Stacked bar charts stack horizontal bars that represent different groups one after another. The length of the stacked bar shows the combined value of the groups. They show the cumulative values of data items and compare parts to the whole.
More about: Stacked bar chart
Basic stacked bar chart
# import libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from textwrap import wrap
'unhcrpyplotstyle','bar'])
plt.style.use([
#load data set
= pd.read_csv('https://raw.githubusercontent.com/GDS-ODSSS/unhcr-dataviz-platform/master/data/comparison/bar_stacked.csv')
df
#reshape df from long to wide
= df.pivot(index='country_origin', columns='population_type', values='population_number')
df = df.reset_index()
df
#sort by total descending order
'Total'] = df.sum(numeric_only=True, axis=1)
df[= df.sort_values("Total", ascending=True)
df = df.fillna(0)
df
#prepare data array for plotting
= df['country_origin']
x
= df['REF']
y1 = df['VDA']
y2 = df['ASY']
y3 = np.add(y1, y2)
b_y3
#wrap long labels
= [ '\n'.join(wrap(l, 20)) for l in x ]
x
#plot the chart
= plt.subplots()
fig, ax =ax.barh(x, y1, label='Refugees')
rect1=ax.barh(x, y2, left=y1, label='Venezuelans dispalced abrod')
rect2=ax.barh(x, y3, left=b_y3, label='Asylum-seekers')
rect3
#set chart title
'People displaced across borders by country of origin | 2021')
ax.set_title(
#set chart legend
=(0,1.02), ncol=3)
ax.legend(loc
#set y-axis title
'Number of people (millions)')
ax.set_xlabel(
#set y-axis label
=True)
ax.tick_params(labelbottom
#show grid below the bars
='x')
ax.grid(axis
#format x-axis tick labels
def number_formatter(x, pos):
if x >= 1e6:
= '{:1.0f}M'.format(x*1e-6)
s elif x < 1e6 and x >= 1e3:
= '{:1.0f}K'.format(x*1e-3)
s else:
= '{:1.0f}'.format(x)
s return s
ax.xaxis.set_major_formatter(number_formatter)
#set chart source and copyright
'Source: UNHCR Refugee Data Finder', (0,0), (0, -40), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
plt.annotate('©UNHCR, The UN Refugee Agency', (0,0), (0, -50), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
plt.annotate(
#adjust chart margin and layout
fig.tight_layout()
#show chart
plt.show()
Stacked bar chart with data label
# import libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from textwrap import wrap
'unhcrpyplotstyle','bar'])
plt.style.use([
#load data set
= pd.read_csv('https://raw.githubusercontent.com/GDS-ODSSS/unhcr-dataviz-platform/master/data/comparison/bar_stacked.csv')
df
#reshape df from long to wide
= df.pivot(index='country_origin', columns='population_type', values='population_number')
df = df.reset_index()
df
#sort by total descending order
'Total'] = df.sum(numeric_only=True, axis=1)
df[= df.sort_values("Total", ascending=True)
df = df.fillna(0)
df
#compute data array for plotting
= df['country_origin']
x = df['REF']
y1 = df['VDA']
y2 = df['ASY']
y3 = np.add(y1, y2)
b_y3
#wrap long labels
= [ '\n'.join(wrap(l, 20)) for l in x ]
x
#plot the chart
= plt.subplots()
fig, ax =ax.barh(x, y1,label='Refugees')
rect2=ax.barh(x, y2, left=y1, label='Venezuelans dispalced abrod')
rect1=ax.barh(x, y3, left=b_y3, label='Asylum-seekers')
rect3
#set chart title
'People displaced across borders by country of origin | 2021', pad=50)
ax.set_title(
#set subtitle
'Number of people in millions', x=0.362, y=0.88)
plt.suptitle(
#set chart legend
=(0,1.02), ncol=3)
ax.legend(loc
# set formatted data label
=[f'{x*1e-6:,.1f}' for x in rect1.datavalues], label_type='center', padding=3,color='#ffffff')
ax.bar_label(rect1, labels=[f'{x*1e-6:,.1f}' for x in rect2.datavalues], label_type='center', padding=3,color='#ffffff')
ax.bar_label(rect2, labels=[f'{x*1e-6:,.1f}' for x in rect3.datavalues], label_type='center', padding=3,color='#ffffff')
ax.bar_label(rect3, labels
#set chart source and copyright
'Source: UNHCR Refugee Data Finder', (0,0), (0, -10), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
plt.annotate('©UNHCR, The UN Refugee Agency', (0,0), (0, -20), xycoords='axes fraction', textcoords='offset points', va='top', color = '#666666', fontsize=9)
plt.annotate(
#adjust chart margin and layout
fig.tight_layout()
#show chart
plt.show()