Home > Back-end >  Annotating heatmap in matplotlib
Annotating heatmap in matplotlib

Time:05-19

I have to do three plots (contour, 3d surface, and heatmap) in matplotlib. The corresponding grid dimension for the three plots are ([0, 0], [0, 1], and [1, 0:1])

I have a few problems

  1. The text annotation for heatmap (ax3), seem to fly out of ax3, into ax1 and ax2. How can I constrain them to be within the ax3 only ?

  2. Is this the fastest way to annotate text assuming that I do not want to use seaborn ?

Can I get some tips on how to resolve my problems ?

Below is the code snippet to perform the plot operation

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gspec
from scipy.interpolate import griddata
import pyautogui
from scipy import stats

x = pyautogui.size()
width = x.width
height = x.height

x = np.arange(0, 10, 0.5)
y = np.arange(0, 10, 0.5)
X, Y = np.meshgrid(x, y)
data = 2 * (np.sin(X)   np.sin(3 * Y))

fig = plt.figure()
fig.set_figheight(height / 100)
fig.set_figwidth(width / 100)
fig.set_dpi(100)
gs = gspec.GridSpec(nrows=2, ncols=2)
ax1 = plt.subplot(gs[0, 0])
ax2 = plt.subplot(gs[0, 1], projection='3d')
ax3 = plt.subplot(gs[1, 0:1])
ctr = ax1.contourf(X, Y, data, 10, cmap='viridis')
ax1.clabel(ctr, inline=True, fontsize=8)
cbar = plt.colorbar(ctr, ax=ax1)
cbar.set_label('ColorbarLabel', size=15)
surf = ax2.plot_surface(X, Y, data, cmap='jet')
cbar1 = plt.colorbar(surf, ax=ax2)
cbar1.set_label('Colorbar2', size=15)
hmap = ax3.pcolormesh(X, Y, data, cmap='viridis')
cbar2 = plt.colorbar(hmap, ax=ax3)
for y in range(data.shape[0]):
    for x in range(data.shape[1]):
        ax3.text(x, y, '%.1f' % data[y, x], size=3)

CodePudding user response:

I assume you want your heatmap to cover both columns. To achieve that you have to use ax3 = plt.subplot(gs[1, 0:2]): this tells matplotlib to use columns 0 and 1 (2 is excluded).

The text annotation for heatmap (ax3), seem to fly out of ax3, into ax1 and ax2. How can I constrain them to be within the ax3 only ?

That's because you are using the wrong coordinates in ax3.text.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gspec
from scipy.interpolate import griddata
import pyautogui
from scipy import stats

x = pyautogui.size()
width = x.width
height = x.height

x = np.arange(0, 10, 0.5)
y = np.arange(0, 10, 0.5)
X, Y = np.meshgrid(x, y)
data = 2 * (np.sin(X)   np.sin(3 * Y))

fig = plt.figure()
fig.set_figheight(height / 100)
fig.set_figwidth(width / 100)
fig.set_dpi(100)
gs = gspec.GridSpec(nrows=2, ncols=2)
ax1 = plt.subplot(gs[0, 0])
ax2 = plt.subplot(gs[0, 1], projection='3d')
ax3 = plt.subplot(gs[1, 0:2])
ctr = ax1.contourf(X, Y, data, 10, cmap='viridis')
ax1.clabel(ctr, inline=True, fontsize=8)
cbar = plt.colorbar(ctr, ax=ax1)
cbar.set_label('ColorbarLabel', size=15)
surf = ax2.plot_surface(X, Y, data, cmap='jet')
cbar1 = plt.colorbar(surf, ax=ax2)
cbar1.set_label('Colorbar2', size=15)
hmap = ax3.pcolormesh(X, Y, data, cmap='viridis')
cbar2 = plt.colorbar(hmap, ax=ax3)
for i in range(data.shape[0]):
    for j in range(data.shape[1]):
        ax3.text(x[j], y[i], '%.1f' % data[i, j], size=5)
  • Related