96 of 100: Matrix chart in matplotlib
At the beginning of the year I challenged myself to create all 100 visualizations using python and matplotlib from the 1 dataset,100 visualizations project and I am sharing with you the code for all the visualizations.
Note: Data Viz Project is copyright Ferdio and available under a Creative Commons Attribution – Non Commercial – No Derivatives 4.0 International license. I asked Ferdio and they told me they used a Design tool to create all the plots.
Collaborate
There are a ton of improvements that can be made on the code, so let me know in the comments any improvements you make and I will update the post accordingly!
To be improved, I need to add the shading to the flags, and find a better way to position the x,y labels.
This is the original viz that we are trying to recreate in matplotlib:

Import the packages
We will need the following packages:
import matplotlib.pyplot as plt
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
Generate the data
The data for this chart has been hardcoded to create a mosaic.
img = [no,sw,no,de,sw,
sw,sw,sw,sw,
de,sw,de,
no,sw,
sw]
img_texts = ["+4", "+5", "+3", "+2", "+7",
"+11","+2","+10","+5",
"+6","+3","+5",
"+1","+8",
"+9"]
Define the variables
no = plt.imread("flags/no-sq.png")
sw = plt.imread("flags/sw-sq.png")
de = plt.imread("flags/de-sq.png")
Plot the chart
ax = plt.figure().subplot_mosaic(
"""
abcde
fghiX
jklXX
mnXXX
oXXXX
""",
empty_sentinel="X",
gridspec_kw={
"wspace": 0,
"hspace": 0,
},
)
def ax_flag(img, ax,xy, x, y):
image_box = OffsetImage(img, zoom = 0.05) #container for the image
ab = AnnotationBbox(image_box, xy, xybox=(x, y), xycoords='data',
boxcoords="offset points",frameon = False)
ax.add_artist(ab)
for im,img_text, (k,ax) in zip(img,img_texts, ax.items()):
ax_flag(im,ax, (0.5,0.5), 0.5,0.5)
ax.text(0.5, 0.1, img_text, transform=ax.transAxes, ha="center", va="center", fontsize=10, color="darkgrey")
ax.set_xticklabels([])
ax.set_yticklabels([])
ax.tick_params(length = 0)
ax.spines[['top','left','bottom','right']].set_color("#D9DDDE")
#set flags in x and y labels
labels_countries = [de, sw, no, de, sw, no, no, sw, de, no, sw, de]
positionx = [35,-35,-105,-180,-250, -320] + [105]*6
postiony = [240]*6 +[185, 130, 80, 25, -25, -75]
for country, posx, posy in zip(labels_countries, positionx, postiony):
ax_flag(country, ax, (1,1), -posx,posy)
#(length, position)
ax.annotate('', xy=(0.3,6.2), xytext=(2.7,6.2),
arrowprops=dict(arrowstyle= '-', lw= 0.5, color='#C0C6CA'), va='center',annotation_clip=False,)
ax.annotate('', xy=(3.3,6.2), xytext=(5.7,6.2),
arrowprops=dict(arrowstyle= '-', lw= 0.5, color='#C0C6CA'), va='center',annotation_clip=False,)
ax.annotate('', xy=(-1,2.3), xytext=(-1,4.7),
arrowprops=dict(arrowstyle= '-', lw= 0.5, color='#C0C6CA'), va='center',annotation_clip=False,)
ax.annotate('', xy=(-1,-0.7), xytext=(-1,1.7),
arrowprops=dict(arrowstyle= '-', lw= 0.5, color='#C0C6CA'), va='center',annotation_clip=False,)
ax.annotate("2004",xy=(1.25,6.15), size=10,color='#C0C6CA',
bbox=dict(boxstyle="square,pad=1",fc="w", ec="w", lw=2),annotation_clip=False,)
ax.annotate("2022",xy=(4.25,6.15), size=10,color='#C0C6CA',
bbox=dict(boxstyle="round,pad=0.4",fc="#ECEFEF", ec="w", lw=2),annotation_clip=False,)
ax.annotate("2004",xy=(-1.05,0.4), size=10,color='#C0C6CA', rotation= 90,
bbox=dict(boxstyle="square,pad=1",fc="w", ec="w", lw=2),annotation_clip=False,)
ax.annotate("2022",xy=(-1.05,3.3), size=10,color='#C0C6CA',rotation= 90,
bbox=dict(boxstyle="round,pad=0.4",fc="#ECEFEF", ec="w", lw=2),annotation_clip=False,)
The result:

Reader Interactions