Generate the data and import packages¶
First, we need to create the data. I'll start by defining it as a dictionary and then convert it into a pandas DataFrame, since pandas is commonly used in many projects for data manipulation.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
color_dict = {"Norway": "#2B314D", "Denmark": "#A54836", "Sweden": "#5375D4" }
xy_ticklabel_color, grid_color, bar_color , datalabels_color ="#101628", "#C8C9C9","#D3D9DB", "#FFFFFF"
data = {
"year": [2004, 2022, 2004, 2022, 2004, 2022],
"countries" : ["Sweden", "Sweden", "Denmark", "Denmark", "Norway", "Norway"],
"sites": [13,15,4,10,5,8]
}
df= pd.DataFrame(data)
df = df.sort_values([ 'countries'], ascending = True).reset_index(drop=True)
#map the colors of a dict to a dataframe
df['color']= df.countries.map(color_dict)
df
| year | countries | sites | color | |
|---|---|---|---|---|
| 0 | 2004 | Denmark | 4 | #A54836 |
| 1 | 2022 | Denmark | 10 | #A54836 |
| 2 | 2004 | Norway | 5 | #2B314D |
| 3 | 2022 | Norway | 8 | #2B314D |
| 4 | 2004 | Sweden | 13 | #5375D4 |
| 5 | 2022 | Sweden | 15 | #5375D4 |
Define x and y coordinates:
unique_countries = df.countries.unique()
unique_years = df.year.unique()
xmax = df.sites.max()
x = np.arange(1,xmax+1)
y = 1
Plot the chart¶
fig, axes = plt.subplots(nrows = len(unique_countries), ncols = len(unique_years), figsize=(10,4), facecolor = "w")
fig.tight_layout(w_pad = 5, h_pad = 2.5 )
colors = []
for i, (row, ax) in enumerate(zip(df.itertuples(), axes.ravel())):
if i% 2==0: #if even
color = [bar_color] *(xmax-row.sites) +[row.color]*row.sites
colors.append(color)
else:
color = [row.color]*row.sites +[row.color] *(xmax-row.sites)
colors.append(color)
#add the country labels
ax.set_ylabel(
row.countries,
rotation= 0,
va= "center",
labelpad = 43
)
ax.bar(
x,
y,
width=0.4,
color= color
)
ax.tick_params(labelleft = False, labelbottom = False, length = 0)
ax.set_frame_on(False)
Add the year labels:
for ax, year in zip(axes[len(unique_countries)-1], unique_years):
ax.annotate(
year,
xy=((xmax+1)/2, -0.5),
xytext=((xmax+1)/2, -2),
annotation_clip=False,
fontsize=14,
ha='center',
va='bottom',
xycoords='data',
color=xy_ticklabel_color,
arrowprops=dict(
arrowstyle='-[, widthB=10, lengthB=.01',
lw=1.0,
color=grid_color
),
bbox = dict(
pad=15,
fc= "none",
ec= "none")
)
fig