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", "#C8C9C9", "#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)
df = df.sort_values(['year' ,'countries', 'sites' ], ascending = False ).reset_index(drop=True)
df["rank"] = df.groupby("year")["sites"].rank().astype(int)
#map the colors of a dict to a dataframe
df['color']= df.countries.map(color_dict)
df
| year | countries | sites | rank | color | |
|---|---|---|---|---|---|
| 0 | 2022 | Sweden | 15 | 3 | #5375D4 |
| 1 | 2022 | Norway | 8 | 1 | #2B314D |
| 2 | 2022 | Denmark | 10 | 2 | #A54836 |
| 3 | 2004 | Sweden | 13 | 3 | #5375D4 |
| 4 | 2004 | Norway | 5 | 2 | #2B314D |
| 5 | 2004 | Denmark | 4 | 1 | #A54836 |
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())))
colors = df.color
sites = df.sites
years = df.year.unique()
countries = df.countries.unique()
fig, ax = plt.subplots(figsize=(10,6), facecolor = "#FFFFFF")
ax.set(xlim = (-0.5,2.5), ylim = (-0.5,1.5))
ax.scatter(
x,
y,
s=sites*800,
alpha=0.9,
color = colors,
zorder = 0
)
ax.scatter(
x,
y,
s=1000,
marker=icon_marker,
color = colors,
zorder=1
)
<matplotlib.collections.PathCollection at 0x284924c9160>
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,
weight = "bold"
)
fig
ax.tick_params(
axis='both',
which='major',
labeltop=True,
labelbottom=False,
length=0,
labelsize=12,
colors= xy_ticklabel_color
)
ax.spines[["bottom",'top','left','right']].set_visible(False)
ax.yaxis.set_ticks(range(len(years)), labels =years)
ax.xaxis.set_ticks(range(len(countries)), labels = countries)
fig