Image Plots

Visualizing 2D Data as Images

Spectrograms, channel matrices, heatmaps of antenna array patterns, and 2D probability distributions are all best visualized as image plots. Matplotlib provides imshow for regular grids and pcolormesh for non-uniform grids, both with rich colormap support.

Definition:

imshow β€” Display a 2D Array as an Image

ax.imshow(Z, cmap, norm, aspect, extent, **kwargs) maps a 2D array ZijZ_{ij} to colored pixels:

ax.imshow(spectrogram_db, cmap='viridis', aspect='auto',
          extent=[t_min, t_max, f_min, f_max], origin='lower')

Key parameters:

  • cmap: colormap name (e.g., 'viridis', 'RdBu_r')
  • extent: [left, right, bottom, top] for axis labeling
  • origin: 'lower' puts row 0 at the bottom (physical convention)
  • aspect: 'auto' stretches to fill; 'equal' preserves pixel ratio
  • norm: Normalize, LogNorm, SymLogNorm for nonlinear mapping

Definition:

pcolormesh β€” Non-Uniform 2D Grid

ax.pcolormesh(X, Y, Z, cmap, shading, **kwargs) draws colored quadrilaterals for non-uniform or curvilinear grids:

X, Y = np.meshgrid(freq_bins, time_bins)
ax.pcolormesh(X, Y, power_db, cmap='inferno', shading='gouraud')

Unlike imshow, pcolormesh handles non-uniform spacing and arbitrary quadrilateral cells.

Use shading='gouraud' for smooth interpolation or shading='flat' for sharp cell boundaries.

Theorem: Perceptual Uniformity of Colormaps

A perceptually uniform colormap maps equal steps in data to equal perceived changes in color. For a colormap C:[0,1]β†’RGBC: [0,1] \to \text{RGB} and lightness function LL:

dLdvβ‰ˆconstβˆ€β€‰v∈[0,1]\frac{dL}{dv} \approx \text{const} \quad \forall\, v \in [0, 1]

viridis, plasma, inferno, and magma satisfy this property. The legacy jet colormap violates it β€” its lightness is non-monotonic, creating false features in images.

If you print a jet figure in grayscale, bright yellow and dark blue both appear as similar grays, hiding real structure. viridis maps monotonically from dark to bright.

Example: Plotting a Spectrogram with imshow

Compute and display the spectrogram of a chirp signal using scipy.signal.spectrogram and ax.imshow.

Colormap Comparison

Compare how different colormaps render the same 2D data. Notice how jet creates false features while viridis preserves the structure.

Parameters

Common Mistake: imshow Origin Convention

Mistake:

Forgetting origin='lower' when plotting physical data. By default imshow uses matrix convention (row 0 at top), which inverts frequency/height axes.

Correction:

Always set origin='lower' for physical data:

ax.imshow(Z, origin='lower', extent=[...])

Quick Check

Why is the 'jet' colormap considered problematic for scientific data?

It has too few colors

It is not perceptually uniform β€” equal data steps do not map to equal perceived color changes

It only works with integer data

It is too slow to render

Why This Matters: Channel Matrix Heatmaps

In MIMO systems, the channel matrix H∈CNrΓ—Nt\mathbf{H} \in \mathbb{C}^{N_r \times N_t} is often visualized as a heatmap with imshow(np.abs(H), cmap='viridis'). This reveals antenna correlation structure, rank deficiency, and spatial selectivity at a glance β€” information that raw numbers cannot convey efficiently.

See full treatment in Chapter 17

Colormap

A mapping from scalar values to colors, used by imshow, pcolormesh, and scatter to encode data magnitude as color.

Related: Colorbar

Colorbar

A legend that shows the mapping between data values and colors in an image plot.