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.
# tutorial
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
color_dict = {
2022: "#CC5A43",
2004: "#5375D4",
}
xy_ticklabel_color, datalabels_color = "#757C85", "#FFFFFF"
data = {
"year": [2004, 2022, 2004, 2022, 2004, 2022],
"countries": ["Denmark", "Denmark", "Norway", "Norway", "Sweden", "Sweden"],
"sites": [4, 10, 5, 8, 13, 15],
}
df = pd.DataFrame(data)
df["ctry_code"] = df.countries.astype(str).str[:2].astype(str).str.upper()
df["year_lbl"] = "'" + df["year"].astype(str).str[-2:].astype(str)
sort_order_dict = {"Denmark": 2, "Sweden": 3, "Norway": 1, 2004: 4, 2022: 5}
df = df.sort_values(
by=[
"countries",
"year",
],
key=lambda x: x.map(sort_order_dict),
)
df["color"] = df.year.map(color_dict)
df
| year | countries | sites | ctry_code | year_lbl | color | |
|---|---|---|---|---|---|---|
| 2 | 2004 | Norway | 5 | NO | '04 | #5375D4 |
| 3 | 2022 | Norway | 8 | NO | '22 | #CC5A43 |
| 0 | 2004 | Denmark | 4 | DE | '04 | #5375D4 |
| 1 | 2022 | Denmark | 10 | DE | '22 | #CC5A43 |
| 4 | 2004 | Sweden | 13 | SW | '04 | #5375D4 |
| 5 | 2022 | Sweden | 15 | SW | '22 | #CC5A43 |
years = df.year.unique()
countries = df.countries.unique()
max_site = df.sites.max()
fig, axes = plt.subplots(ncols=len(years), nrows=len(countries), figsize=(5, 5), sharex=True, sharey=True, facecolor="#FFFFFF")
for ax, row in zip(axes.ravel(), df.itertuples()):
site = row.sites
x = list(np.arange(0, site, 1))
y = list(reversed(np.arange(16 - site, 16, 1)))
ax.plot(
x,
y,
"-",
lw=30,
color=row.color,
solid_capstyle="round",
zorder=0,
)
ax.scatter(
0,
max_site,
s=860,
color="#2C324F",
zorder=2,
)
ax.annotate(
site,
(0, max_site),
size=12,
color=datalabels_color,
ha="center",
va="center",
)
ax.set_frame_on(False)
ax.tick_params(
length=0,
labelbottom=False,
labelleft=False
)
ax.set(xlim=(-4, 20), ylim=(-4, 22))
for ax, country in zip(axes[:, 0], countries):
ax.set_ylabel(
country,
rotation = 0,
size = 12,
color = xy_ticklabel_color,
labelpad = 53
)
for ax, year in zip(axes[0], years):
ax.set_title(
year,
x = 0.5,
y = 1.2,
color = xy_ticklabel_color,
)