Print

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:

96 of 100: Matrix chart in matplotlib
Was this helpful?

Reader Interactions

Leave a Reply

Your email address will not be published. Required fields are marked *

Table of Contents