How to replace heatmap axis ticklabels with png icon images

54 Views Asked by At

I've got a datafile with the percentages to which different political parties agree on issues. And I'm using matplotlib to generate a heatmap, but in the final chart I want to replace the text labels on both the x-axis and the y-axis with the logo of each party. I've got each logo prepared as a PNG image file and I've got a list of these filenames. Here is the code so far.

# Library
import pandas as pd
import io
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap

# read csv file
filename = "PartyAgreePerc.csv"
#df_perc = pd.read_csv(filename, sep=';', header=0)
str_parties = """Party1;Party2;AgreePerc
PartyA;PartyB1;55
PartyA;GrParty;57
PartyA;PartyD6;19
PartyA;PartyV;27
PartyB1;GrParty;33
PartyB1;PartyD6;-6
PartyB1;PartyV;23
GrParty;PartyD6;45
GrParty;PartyV;36
PartyD6;PartyV;62
"""
df_perc = pd.read_csv(io.StringIO(str_parties), sep = ";", decimal=".")

# add mirrored percentages (add flipped Party1/Party2 percentages)
df_perc_copy = df_perc.copy()
df_perc_copy['Party1'], df_perc_copy['Party2'] = df_perc['Party2'], df_perc['Party1']

# merge
df_perc = pd.concat([df_perc, df_perc_copy], ignore_index=True)

# determine unique parties
all_parties = set(df_perc['Party1'].unique()) | set(df_perc['Party2'].unique())
print("All parties: ", all_parties)
      
# logically, each party agrees 100% with itself
party_itself = [{'Party1': party, 'Party2': party, 'AgreePerc': 100} for party in all_parties]

df_perc = pd.concat([df_perc, pd.DataFrame(party_itself)], ignore_index=True)

# maak een pivot table
df_heatmap = df_perc.pivot(index='Party1', columns='Party2', values='AgreePerc')
#df_heatmap = df_heatmap.reindex(index=all_parties, columns=all_parties)

# genereer heatmap
fig, ax = plt.subplots(figsize=(10, 8))

# Plot the heatmap
cax = ax.matshow(df_heatmap, cmap='coolwarm_r') # Spectral, bwn, coolwarm, seismic etc "_r" for reversed

# Set axis labels and titles
ax.set_xticks(np.arange(len(df_heatmap.columns)))
ax.set_yticks(np.arange(len(df_heatmap.index)))

ax.set_xticklabels(df_heatmap.columns)
ax.set_yticklabels(df_heatmap.columns)

plt.title('Party - Agree Percentages')

# Annotate the heatmap cells with percentage values
for i in range(len(all_parties)):
    for j in range(len(all_parties)):
        value = df_heatmap.iloc[i, j]
        v_color = 'black'
        if value > 50 or value < -20:
            v_color = 'w'
        ax.text(j, i, f'{value:.0f}%', ha='center', va='center', color=v_color, fontsize=10)

# HOW TO REPLACE TEXTS WITH ICONS?
party_icons = [party + ".png" for party in all_parties]
print(party_icons)
#plt.xticks(party_icons)

# Rotate the tick labels for better readability if needed
plt.xticks(rotation=90)

# Display the heatmap
plt.show()

This works and it generates a heatmap like below:

enter image description here

In the code there's also a variable party_icons which contains the list of all PNG names for the parties ['PartyV.png', 'PartyD6.png', 'PartyA.png', 'GrParty.png', 'PartyB1.png']. But how do I use this party_icons list to add the PNG logos to both the x-axis and y-axis?

0

There are 0 best solutions below