Data Visualization
Heatmap
2D Plotting
Matplotlib
Python Programming

Plotting a 2D heatmap

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

A 2D heatmap displays a matrix of values by mapping numbers to colors. It is useful when the structure of the data matters as much as the individual values, such as correlation matrices, confusion matrices, grid simulations, and image-like arrays.

The key decisions are usually not "how do I draw colored squares" but "what does each axis mean" and "how should the color scale be interpreted."

A Basic Heatmap with Matplotlib

For matrix-shaped data, matplotlib.pyplot.imshow is the most direct starting point.

python
1import numpy as np
2import matplotlib.pyplot as plt
3
4data = np.array(
5    [
6        [1, 3, 5, 7],
7        [2, 4, 6, 8],
8        [3, 5, 7, 9],
9    ]
10)
11
12plt.imshow(data, cmap="viridis", aspect="auto")
13plt.colorbar(label="Intensity")
14plt.title("Basic 2D Heatmap")
15plt.xlabel("Column")
16plt.ylabel("Row")
17plt.show()

imshow treats the input as an image-like grid. The colorbar is important because it explains what the colors mean numerically.

Labeling Axes Clearly

If your rows and columns have names, add tick labels so the heatmap is interpretable:

python
1import numpy as np
2import matplotlib.pyplot as plt
3
4data = np.array(
5    [
6        [0.82, 0.65, 0.91],
7        [0.74, 0.88, 0.79],
8        [0.69, 0.72, 0.95],
9    ]
10)
11
12rows = ["Model A", "Model B", "Model C"]
13cols = ["Accuracy", "Recall", "Precision"]
14
15fig, ax = plt.subplots()
16image = ax.imshow(data, cmap="magma", vmin=0, vmax=1)
17
18ax.set_xticks(range(len(cols)))
19ax.set_xticklabels(cols)
20ax.set_yticks(range(len(rows)))
21ax.set_yticklabels(rows)
22
23fig.colorbar(image, ax=ax, label="Score")
24plt.show()

Without labels, a heatmap often looks impressive but explains very little.

Annotating Cell Values

For smaller matrices, adding text values inside each cell can make the chart much easier to read:

python
1import numpy as np
2import matplotlib.pyplot as plt
3
4data = np.array([[12, 8, 3], [6, 14, 5], [2, 7, 11]])
5
6fig, ax = plt.subplots()
7image = ax.imshow(data, cmap="Blues")
8
9for row_index in range(data.shape[0]):
10    for col_index in range(data.shape[1]):
11        ax.text(
12            col_index,
13            row_index,
14            data[row_index, col_index],
15            ha="center",
16            va="center",
17            color="black",
18        )
19
20fig.colorbar(image, ax=ax)
21plt.title("Annotated Heatmap")
22plt.show()

This works well for dashboards, reports, and confusion matrices with a manageable number of cells.

When Seaborn Is More Convenient

If you want labels, annotations, and a polished default style with less code, Seaborn is often more convenient:

python
1import pandas as pd
2import seaborn as sns
3import matplotlib.pyplot as plt
4
5df = pd.DataFrame(
6    [[12, 8, 3], [6, 14, 5], [2, 7, 11]],
7    index=["Class A", "Class B", "Class C"],
8    columns=["Pred A", "Pred B", "Pred C"],
9)
10
11sns.heatmap(df, annot=True, fmt="d", cmap="YlGnBu")
12plt.title("Confusion Matrix Heatmap")
13plt.show()

Seaborn is especially pleasant when the data already lives in a Pandas DataFrame.

Choosing a Good Color Scale

Colormap choice affects interpretation. Sequential colormaps such as viridis or Blues are good for values that go from low to high. Diverging colormaps are better when the midpoint matters, such as positive versus negative deviations around zero.

It also helps to set vmin and vmax deliberately. Otherwise, each plot may auto-scale differently, making side-by-side comparison misleading.

For example:

python
plt.imshow(data, cmap="coolwarm", vmin=-1, vmax=1)

That is appropriate for values centered around zero, such as residuals or correlations.

Common Pitfalls

The most common problem is plotting the matrix without a colorbar. Without a legend, viewers can see the pattern but not the meaning of the colors.

Another issue is using the wrong aspect ratio. A square matrix usually looks best with square cells, while rectangular business tables may need aspect="auto" so labels fit cleanly.

Developers also sometimes choose colormaps with poor contrast or misleading perceptual jumps. A heatmap is not only decoration; the color encoding is the data.

Finally, be careful with very large matrices. A dense heatmap with thousands of rows and columns becomes unreadable. In those cases, consider aggregation, clustering, or interactive zooming.

Summary

  • A 2D heatmap maps matrix values to colors and works best when both axes are meaningful.
  • 'imshow is the simplest Matplotlib entry point for matrix-like data.'
  • Add labels, annotations, and a colorbar to make the plot interpretable.
  • Use Seaborn when you want a cleaner high-level API for labeled data frames.
  • Choose colormaps and value ranges deliberately so the color scale communicates the right story.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.