I want to make this type of graph you see below. I get that I can make a matrix graph with matplotlib like so
cmap = colors.ListedColormap(['white','red'])
data = [
[0,0,0,0,0,1,1,1,1,],
[0,0,0,0,0,1,0,0,1,],
]
plt.figure(figsize=(9,5))
plt.pcolor(data[::-1],cmap=cmap,edgecolors='k', linewidths=3)
plt.xlabel('Problem')
plt.ylabel('Particpant')
plt.show()
But how would I go about adding percentages to be included in this graph?
CodePudding user response:
You can add a secondary x-axis (ax.twiny()
), using the top axis for the numbering and the bottom axis to show the percentages.
Calling pcolor
with a list of x and y positions that are 0.5 shifted will put the ticks and tick labels at integer positions. clip_on=False
makes sure the outer cell borders have the same thickness as the rest. ax.invert_yaxis()
lets you invert the y axis (so you can use data
instead of data[::-1]
).
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import numpy as np
cmap = ListedColormap(['white', 'orangered'])
data = np.random.randint(0, 3, size=(28, 30)) % 2
data[:, 9] = 1 # one full column to simulate 100%
data[:, 11] = 0 # one empty column to simulate 0%
fig, ax = plt.subplots(figsize=(9, 5))
ax.pcolor(np.arange(data.shape[1] 1) 0.5, np.arange(data.shape[0] 1) 0.5, data,
cmap=cmap, edgecolors='k', linewidths=3, clip_on=False)
ax.set_yticks(range(1, data.shape[0] 1))
ax.set_xticks(range(1, data.shape[1] 1))
ax.set_xticklabels([f'{p:.0f}' for p in data.mean(axis=0) * 100])
ax.invert_yaxis()
ax2 = ax.twiny()
ax2.set_xlim(ax.get_xlim())
ax2.set_xticks(range(1, data.shape[1] 1))
ax2.set_xlabel('Problem')
ax.tick_params(length=0)
ax2.tick_params(length=0)
ax.set_ylabel('Particpant')
plt.tight_layout()
plt.show()
Decreasing the fontsize (or increasing the figsize
) allows to also show the percentage sign:
ax.set_xticklabels([f'{p:.0f}%' for p in data.mean(axis=0) * 100], fontsize=8)