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:
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?