Annotating matplotlib heatmap

Viewed 87

I created a simple heatmap on Matplotlib on a already existing image, now i'm trying to show the values on the cells, but the problem is that the values won't go inside the heatmap, but all around the image, here is a screenshot.

I think this happens because i'm generating the heatmap on top of an image, but i don't know how to fix that. Here is my code:

fig,ax = plt.subplots(1)

ax.imshow(im)

a = [[0.0233188  0.0232844  0.0233099  0.0242786 ]
     [0.0233158  0.023217   0.02370096 0.02434176]
     [0.02328474 0.02319508 0.02433976 0.02290478]
     [0.02320107 0.02345002 0.02484117 0.02355316]
     [0.02317872 0.02374418 0.02374605 0.02157998]]

ax1 = fig.add_subplot(111)

bounds1 = sorted([0.023,  np.amin(a), np.amax(a)])
norm1 = matplotlib.colors.TwoSlopeNorm(vcenter=bounds1[1], vmin=bounds1[0], vmax=bounds1[2])

Map = ax1.imshow(a, interpolation='none', norm=norm1, extent=[0, 1.15, 0, 0.85])

x1 = [1, 2, 3, 4]
y1 = [1, 2, 3, 4, 5]

for i in range(len(y1)):
    for j in range(len(x1)):
        text = ax1.text(j, i, a[i, j],
                       ha="center", va="center", color="r")
1 Answers

extent=[x0, x1, y0, y1] changes the x and y coordinates of the image. When there are N cells between x0 and x1, the cell centers can be found by splitting the distance into 2N+1 parts and taking the 1st, 3rd, 5th, ... position of that list.

Note that as imshow(a, ...) didn't use origin='lower', the values are reversed. So, for the y-positions need to be traversed in reverse order.

from matplotlib import pyplot as plt
import matplotlib
import numpy as np

fig, ax = plt.subplots()
ax.axis('off')

a = np.array([[0.0233188, 0.0232844, 0.0233099, 0.0242786],
              [0.0233158, 0.023217, 0.02370096, 0.02434176],
              [0.02328474, 0.02319508, 0.02433976, 0.02290478],
              [0.02320107, 0.02345002, 0.02484117, 0.02355316],
              [0.02317872, 0.02374418, 0.02374605, 0.02157998]])
ax1 = fig.add_subplot(111)

bounds1 = sorted([0.023, np.amin(a), np.amax(a)])
norm1 = matplotlib.colors.TwoSlopeNorm(vcenter=bounds1[1], vmin=bounds1[0], vmax=bounds1[2])

x0, x1, y0, y1 = 0, 1.15, 0, 0.85
Map = ax1.imshow(a, interpolation='none', norm=norm1, extent=[x0, x1, y0, y1])

for i, yi in enumerate(np.linspace(y0, y1, 2 * a.shape[0] + 1)[-2::-2]):
    for j, xj in enumerate(np.linspace(x0, x1, 2 * a.shape[1] + 1)[1::2]):
        text = ax1.text(xj, yi, f'{a[i, j]:.6f}',
                        ha="center", va="center", color='darkred' if a[i, j] > bounds1[1] else 'white', fontsize=10)
plt.show()

resulting plot

Related