Heatmaps with pcolormesh¶
The ax.pcolormesh() method creates pseudocolor plots with quadrilateral cells, offering more flexibility than imshow for non-uniform grids and coordinate-based data.
Basic pcolormesh¶
Create a heatmap using pcolormesh.
1. Simple Usage¶
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
data = np.random.rand(10, 10)
fig, ax = plt.subplots()
pc = ax.pcolormesh(data)
plt.colorbar(pc)
plt.show()
2. With Coordinates¶
x = np.arange(11) # 11 edges for 10 cells
y = np.arange(11)
X, Y = np.meshgrid(x, y)
fig, ax = plt.subplots()
pc = ax.pcolormesh(X, Y, data)
plt.colorbar(pc)
plt.show()
3. Cell Centers vs Edges¶
# pcolormesh uses edges: N+1 coordinates for N cells
# Data shape (10, 10) needs X, Y shape (11, 11)
imshow vs pcolormesh¶
Understanding when to use each method.
1. Key Differences¶
# imshow:
# - Pixels are uniformly sized
# - Origin at top-left by default
# - Aspect ratio preserved
# - Faster for large uniform grids
# pcolormesh:
# - Cells can be non-uniform
# - Origin at bottom-left by default
# - Aspect ratio follows data coordinates
# - Supports curvilinear grids
2. Origin Behavior¶
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))
ax1.imshow(data)
ax1.set_title('imshow (origin=upper)')
ax2.pcolormesh(data)
ax2.set_title('pcolormesh (origin=lower)')
plt.tight_layout()
plt.show()
3. Matching Origins¶
# Make imshow match pcolormesh
ax.imshow(data, origin='lower')
# Or flip data for pcolormesh to match imshow
ax.pcolormesh(data[::-1])
Non-Uniform Grids¶
pcolormesh excels with irregularly spaced data.
1. Logarithmic Spacing¶
x = np.logspace(0, 2, 11) # 1 to 100, log-spaced
y = np.linspace(0, 10, 11)
X, Y = np.meshgrid(x, y)
data = np.random.rand(10, 10)
fig, ax = plt.subplots()
pc = ax.pcolormesh(X, Y, data)
ax.set_xscale('log')
plt.colorbar(pc)
plt.show()
2. Variable Cell Sizes¶
x = np.array([0, 1, 2, 4, 8, 16]) # Non-uniform spacing
y = np.array([0, 1, 3, 6, 10])
X, Y = np.meshgrid(x, y)
data = np.random.rand(4, 5)
fig, ax = plt.subplots()
pc = ax.pcolormesh(X, Y, data)
plt.colorbar(pc)
plt.show()
3. Time Series Data¶
import datetime
dates = [datetime.datetime(2024, 1, i) for i in range(1, 12)]
hours = np.arange(25)
data = np.random.rand(24, 10)
fig, ax = plt.subplots(figsize=(10, 5))
pc = ax.pcolormesh(dates, hours, data)
ax.set_ylabel('Hour')
plt.colorbar(pc)
plt.show()
Shading Options¶
The shading keyword controls cell rendering.
1. Flat Shading (Default)¶
ax.pcolormesh(X, Y, data, shading='flat')
# Requires X, Y one larger than data in each dimension
2. Auto Shading¶
# Automatically handles coordinate/data size mismatch
ax.pcolormesh(X, Y, data, shading='auto')
3. Gouraud Shading¶
# Interpolated colors at vertices
# Requires X, Y same shape as data
x = np.arange(10)
y = np.arange(10)
X, Y = np.meshgrid(x, y)
ax.pcolormesh(X, Y, data, shading='gouraud')
Edge Colors¶
Add grid lines between cells.
1. Black Edges¶
fig, ax = plt.subplots()
pc = ax.pcolormesh(data, edgecolors='black', linewidth=0.5)
plt.colorbar(pc)
plt.show()
2. White Edges¶
pc = ax.pcolormesh(data, edgecolors='white', linewidth=1)
3. Face Color Only¶
pc = ax.pcolormesh(data, edgecolors='face') # Edges match cell color
Colormap and Range¶
Control color mapping identical to imshow.
1. Colormap Selection¶
pc = ax.pcolormesh(data, cmap='viridis')
pc = ax.pcolormesh(data, cmap='coolwarm')
2. Value Range¶
pc = ax.pcolormesh(data, vmin=0, vmax=1)
3. Centered Diverging¶
data_centered = np.random.randn(10, 10)
max_abs = np.abs(data_centered).max()
pc = ax.pcolormesh(data_centered, cmap='RdBu', vmin=-max_abs, vmax=max_abs)
Masked Data¶
Handle missing or invalid values.
1. Create Masked Array¶
data = np.random.rand(10, 10)
mask = data < 0.2
masked_data = np.ma.masked_array(data, mask)
fig, ax = plt.subplots()
pc = ax.pcolormesh(masked_data)
plt.colorbar(pc)
plt.show()
2. Set Bad Color¶
cmap = plt.cm.viridis.copy()
cmap.set_bad('gray')
pc = ax.pcolormesh(masked_data, cmap=cmap)
3. NaN Values¶
data_with_nan = data.copy()
data_with_nan[data < 0.2] = np.nan
pc = ax.pcolormesh(data_with_nan, cmap=cmap)
Practical Example¶
Create a complete heatmap with pcolormesh.
1. Generate Structured Data¶
x = np.linspace(-3, 3, 50)
y = np.linspace(-3, 3, 50)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)
2. Create Visualization¶
fig, ax = plt.subplots(figsize=(8, 6))
pc = ax.pcolormesh(X, Y, Z, cmap='RdBu', shading='auto')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_title('sin(x) × cos(y)')
ax.set_aspect('equal')
plt.colorbar(pc, label='Value')
plt.tight_layout()
plt.show()
3. Add Contour Overlay¶
fig, ax = plt.subplots(figsize=(8, 6))
pc = ax.pcolormesh(X, Y, Z, cmap='RdBu', shading='auto', alpha=0.8)
ax.contour(X, Y, Z, colors='black', linewidths=0.5, levels=10)
plt.colorbar(pc)
plt.show()