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 matplotlib as mpl
from svgpathtools import svg2paths
from svgpath2mpl import parse_path
import numpy as np
import pandas as pd
color_dict = {"Norway": "#2B314D", "Denmark": "#A54836", "Sweden": "#5375D4"}
xy_ticklabel_color, grand_totals_color, grid_color, datalabels_color ='#757C85',"#101628", "#D4D5D7", "#101628"
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)
#custom sort
sort_order_dict = {"Denmark":2, "Sweden":1, "Norway":3, 2004:5, 2022:4}
df = df.sort_values(by=['year','countries'], key=lambda x: x.map(sort_order_dict))
#map the colors of a dict to a dataframe
df['color']= df.countries.map(color_dict)
df
| year | countries | sites | color | |
|---|---|---|---|---|
| 5 | 2022 | Sweden | 15 | #5375D4 |
| 1 | 2022 | Denmark | 10 | #A54836 |
| 3 | 2022 | Norway | 8 | #2B314D |
| 4 | 2004 | Sweden | 13 | #5375D4 |
| 0 | 2004 | Denmark | 4 | #A54836 |
| 2 | 2004 | Norway | 5 | #2B314D |
icon_path, attributes = svg2paths('../flags/Unesco_World_Heritage_logo_notext_transparent.svg')
#matplotlib path object of the icon
icon_marker = parse_path(attributes[0]['d'])
icon_marker.vertices -= icon_marker.vertices.mean(axis=0)
icon_marker = icon_marker.transformed(mpl.transforms.Affine2D().rotate_deg(180))
icon_marker = icon_marker.transformed(mpl.transforms.Affine2D().scale(-1,1))
x, y = np.meshgrid(
np.arange(len(df.countries.unique())),
np.arange(len(df.year.unique())))
sites = df.sites
years = df.year.unique()
countries = df.countries.unique()
fig, ax = plt.subplots(figsize=(8,4), facecolor = "#FFFFFF")
fig.tight_layout(pad=1.0)
ax.set(xlim = (-0.5,2.5), ylim = (-0.5,1.5))
ax.scatter(
x,
y,
s=sites*400,
marker=icon_marker,
color = df.color,
zorder=1
)
<matplotlib.collections.PathCollection at 0x1bfc4e9a480>
for i, site in enumerate(sites):
ax.annotate(
site,
(x.flatten()[i], y.flatten()[i]-0.4),
ha= "center",
va="center",
size=14,
color= datalabels_color
)
fig
y = [-0.5, 0.4, 1.4]
for y in y:
ax.axhline(
y,
0,
1,
ls = "dotted",
color = grid_color,
clip_on = False
)
fig
ax.tick_params(
axis='both',
which='major',
labeltop=True,
labelbottom=False,
length=0,
labelsize=12,
colors= xy_ticklabel_color,
pad = 2.5
)
ax.set_frame_on(False)
ax.yaxis.set_ticks(range(len(years)), labels =years)
ax.xaxis.set_ticks(range(len(countries)), labels = countries)
fig