24

I m trying to generate heatmaps for the some data and my code is shown below:

data = [['basis', 2007, 2008],
        [1, 2.2, 3.4],
        [2, 0, -2.2],
        [3, -4.1, -2.5],
        [4, -5.8, 1.2],
        [5, -5.4, -3.6],
        [6, 1.4, -5.9]]

x_header = data[0][1:]
y_header = [i for i in range(1, 13)]
data=data[1:]
for i in range(len(data)):
    data[i] = data[i][1:]
arr = np.array(data)
fig, ax = plt.subplots()
#heatmap = plt.pcolor(arr, cmap = 'RdBu')
norm = MidpointNormalize(midpoint=0)
im = ax.imshow(data, norm=norm, cmap=plt.cm.seismic, interpolation='none')

ax.set_xticks(np.arange(arr.shape[1]), minor=False)
ax.set_yticks(np.arange(arr.shape[0]), minor=False)
ax.xaxis.tick_top()
ax.set_xticklabels(x_header, rotation=90)
ax.set_yticklabels(y_header)

fig.colorbar(im)
plt.show()

It generates the image

enter image description here

I also want to show values inside the grid. Is there any way to do that?

Hooked
  • 84,485
  • 43
  • 192
  • 261
sunil_mlec
  • 642
  • 1
  • 8
  • 20

2 Answers2

51

Sure, just do something like:

import matplotlib.pyplot as plt
import numpy as np

data = np.random.random((4, 4))

fig, ax = plt.subplots()
# Using matshow here just because it sets the ticks up nicely. imshow is faster.
ax.matshow(data, cmap='seismic')

for (i, j), z in np.ndenumerate(data):
    ax.text(j, i, '{:0.1f}'.format(z), ha='center', va='center')

plt.show()

enter image description here

However, the labels are hard to see, so you might want a box around them:

import matplotlib.pyplot as plt
import numpy as np

data = np.random.random((4, 4))

fig, ax = plt.subplots()
# Using matshow here just because it sets the ticks up nicely. imshow is faster.
ax.matshow(data, cmap='seismic')

for (i, j), z in np.ndenumerate(data):
    ax.text(j, i, '{:0.1f}'.format(z), ha='center', va='center',
            bbox=dict(boxstyle='round', facecolor='white', edgecolor='0.3'))

plt.show()

enter image description here

Also, in many cases, ax.annotate is more useful that ax.text. It's much more flexible in how you can position text, but it's also more complex. Have a look at the examples here: http://matplotlib.org/users/annotations_guide.html

Joe Kington
  • 275,208
  • 71
  • 604
  • 463
3

If you don't want to use ax you can simply:

plt.matshow(data)

for (x, y), value in np.ndenumerate(data):
    plt.text(x, y, f"{value:.2f}", va="center", ha="center")
Víctor Navarro
  • 812
  • 9
  • 12