Grouped bar chart with Python
Grouped bar charts are a type of colour-coded bar chart that is used to represent and compare different categories of two or more groups.
More about: Grouped bar chart
Basic grouped bar chart
# import libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from textwrap import wrap
plt.style.use(['unhcrpyplotstyle', 'bar'])
#load data set
df = pd.read_csv('https://raw.githubusercontent.com/GDS-ODSSS/unhcr-dataviz-platform/master/data/comparison/bar_grouped.csv')
#reshape df from long to wide
df = df.pivot(index='region', columns='year', values='asylum_application')
df = df.reset_index()
#sort value by descending order
df = df.sort_values(by=['region'], ascending=False)
#compute data array for plotting
labels = df['region']
category1 = df[2019]
category2 = df[2020]
#wrap long labels
labels = [ '\n'.join(wrap(l, 20)) for l in labels ]
#set x-axis ticks label location
x = np.arange(len(labels))
#set bar width
width = 0.4
#plot the chart
fig, ax = plt.subplots()
rects1 = ax.barh(x + width/2, category2, width, edgecolor='white', label=2020)
rects2 = ax.barh(x - width/2, category1, width, edgecolor='white', label=2019)
#set chart title
ax.set_title('Individual asylum applications registered by region | 2019-2020')
#set chart legend
ax.legend(loc=(0,1), ncol=2)
#set y-axis title
ax.set_xlabel('Number of people')
#set y-axis label
ax.tick_params(labelbottom=True)
#set x-axis label
ax.set_yticks(x, labels)
#set x-axis limit
xlimit = plt.xlim(0, 1000000)
#show grid below the bars
ax.grid(axis='x')
#format x-axis tick labels
def number_formatter(x, pos):
if x >= 1e6:
s = '{:1.0f}M'.format(x*1e-6)
elif x < 1e6 and x >= 1e3:
s = '{:1.0f}K'.format(x*1e-3)
else:
s = '{:1.0f}'.format(x)
return s
ax.xaxis.set_major_formatter(number_formatter)
#set chart source and copyright
plt.annotate('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)
#adjust chart margin and layout
fig.tight_layout()
#show chart
plt.show()Grouped bar chart with data label
# import libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from textwrap import wrap
plt.style.use(['unhcrpyplotstyle', 'bar'])
#load data set
df = pd.read_csv('https://raw.githubusercontent.com/GDS-ODSSS/unhcr-dataviz-platform/master/data/comparison/bar_grouped.csv')
#reshape df from long to wide
df = df.pivot(index='region', columns='year', values='asylum_application')
df = df.reset_index()
#sort value in descending order
df = df.sort_values(by=['region'], ascending=False)
#prepare data array for plotting
labels = df['region']
category1 = df[2019]
category2 = df[2020]
#wrap long labels
labels = [ '\n'.join(wrap(l, 20)) for l in labels ]
#set x-axis ticks label location
x = np.arange(len(labels))
#set bar width
width = 0.4
#plot the chart
fig, ax = plt.subplots()
rects1 = ax.barh(x + width/2, category2, width, edgecolor='white', label=2020)
rects2 = ax.barh(x - width/2, category1, width, edgecolor='white', label=2019)
#set chart title
ax.set_title('Individual asylum applications registered by region | 2019-2020', pad=50)
#set subtitle
plt.suptitle('Number of people in thousands', x=0.36, y=0.885)
#set chart legend
ax.legend(loc=(0,1), ncol=2)
#set formatted data label
ax.bar_label(rects1, labels=[f'{x*1e-3:,.0f}' for x in rects1.datavalues], padding=3)
ax.bar_label(rects2, labels=[f'{x*1e-3:,.0f}' for x in rects2.datavalues], padding=3)
#set x-axis tick and label
ax.set_yticks(x, labels)
#set chart source and copyright
plt.annotate('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)
#adjust chart margin and layout
fig.tight_layout()
#show chart
plt.show()