Issue
I'm desperately trying to reproduce this chart done by the Financial Times about covid_19 stringency index for different countries over the last year:
I have all the data on a pandas dataframe but I really can't get my mind around how to do this plot with python and matplotlib/seaborn. I tried with a stacked bar chart but it's not that. My df looks like this:
I know this may sound silly but I just need a hint on what function should I use to reproduce that chart. Thanks so much to anyone who wishes to help me!
Solution
There are many ways to make a comparable plot with matplotlib. In the following approach, pcolor()
is used together with a ListedColormap
and a BoundaryNorm
.
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap, BoundaryNorm
from matplotlib.cm import ScalarMappable
import numpy as np
import seaborn as sns
import pandas as pd
df = pd.read_csv('covid-stringency-index.csv')
df['Day'] = pd.to_datetime(df['Day'])
colors = sns.color_palette('rocket_r', 6)
colors[0] = 'lightblue'
cmap = ListedColormap(colors)
cmap.set_bad('grey')
bounds = [0, 1, 25, 50, 75, 85, 100]
norm = BoundaryNorm(bounds, len(bounds) - 1)
continents = {'Asia': ['Singapore', 'China', 'Japan', 'Philippines', 'Vietnam', 'India', 'South Korea'],
'Americas': ['Colombia', 'Canada', 'Argentina', 'Brazil', 'United States', 'Venezuela',
'Mexico', 'Peru', 'Bolivia', 'Chile']}
fig, ax = plt.subplots(figsize=(12, 8))
labels = []
for continent in continents:
labels.append(continent)
for country in continents[continent]:
labels.append(country)
ind = len(labels) - 1
df1 = df[df['Entity'] == country]
ax.pcolor(df1['Day'], [ind - 0.4, ind + 0.4], df1['stringency_index'][1:].to_numpy().reshape(1, -1), cmap=cmap)
# edgecolor='white', lw=0.2)
ax.set_yticks(np.arange(len(labels)))
ax.set_yticklabels(labels)
ax.set_ylim(-0.5, len(labels) - 0.5)
ax.invert_yaxis()
for spine in ax.spines:
ax.spines[spine].set_visible(False)
ax.tick_params(axis='y', length=0)
for t in ax.get_yticklabels():
if t.get_text() in continents:
t.set_size(16)
cax = fig.add_axes([0.7, 0.95, 0.27, 0.03])
plt.colorbar(ScalarMappable(cmap=cmap, norm=norm), ax=ax, cax=cax,
orientation='horizontal', anchor=(1, 1.02))
plt.subplots_adjust(left=0.2, right=0.97, top=0.95, bottom=0.07)
plt.show()
Answered By - JohanC
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.