matplotlib
savefig
python
troubleshooting
blank image

Savefig outputs blank image

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

When matplotlib.pyplot.savefig() writes a blank image, the problem is usually not the file format itself. In most cases, the figure being saved is empty, the wrong figure is active, or the save happens after a step that clears or replaces the plot state.

Save Before Anything Closes the Figure

The most common mistake is calling plt.show() before plt.savefig(). In some environments, show() displays the figure and then clears or closes it, which means the later save operation writes an empty canvas.

Use this order instead:

python
1import matplotlib.pyplot as plt
2
3x = [1, 2, 3, 4]
4y = [1, 4, 9, 16]
5
6plt.plot(x, y)
7plt.title("Square numbers")
8plt.savefig("plot.png", dpi=150, bbox_inches="tight")
9plt.show()

If your current code saves after show(), reverse the order first. That solves a large share of blank-image cases.

Save the Figure You Actually Drew On

Another frequent issue is mixing pyplot state with figure objects and then saving the wrong one. The most reliable pattern is to use the object-oriented API and call savefig() on the specific Figure instance.

python
1import matplotlib.pyplot as plt
2
3fig, ax = plt.subplots()
4ax.plot([1, 2, 3], [2, 3, 5])
5ax.set_title("Object-oriented API")
6
7fig.savefig("figure_output.png", dpi=150)

This avoids confusion about which figure is currently active. It is especially helpful in scripts that create multiple plots or helper functions that return figures.

Avoid Clearing the Plot Before Saving

Functions such as plt.clf(), plt.close(), and ax.clear() remove plotted content. If one of those runs before the save call, the image file will be blank even though the earlier code looked correct.

This example is wrong:

python
1import matplotlib.pyplot as plt
2
3plt.plot([1, 2, 3], [1, 4, 9])
4plt.clf()
5plt.savefig("blank.png")

This version is correct:

python
1import matplotlib.pyplot as plt
2
3plt.plot([1, 2, 3], [1, 4, 9])
4plt.savefig("not_blank.png")
5plt.clf()

If you are generating figures in a loop, check carefully that cleanup only happens after the file is written.

Headless Environments and Backends

If you run Matplotlib on a server, in CI, or in a container without a GUI, use a non-interactive backend. A headless environment does not need a windowing backend just to save an image.

python
1import matplotlib
2matplotlib.use("Agg")
3
4import matplotlib.pyplot as plt
5
6plt.plot([0, 1], [0, 1])
7plt.savefig("line.png")

The Agg backend is designed for raster image output and is a common choice for scripts and automated jobs.

If you only save files and never display plots interactively, this setup is often more predictable than relying on whatever backend happens to be chosen automatically.

Check That Data and Axis Limits Are Valid

Sometimes the image is not literally blank, but the data is outside the visible range or is entirely NaN. That can look like an empty output even though the file was created correctly.

python
1import matplotlib.pyplot as plt
2
3x = [1, 2, 3]
4y = [float("nan"), float("nan"), float("nan")]
5
6plt.plot(x, y)
7plt.savefig("nan_plot.png")

The file is valid, but no visible line appears because there are no usable points. If the saved image seems empty, inspect the data and confirm the axes contain what you expect.

A Reliable Pattern for Scripts

For automation, use a predictable sequence:

  1. create the figure,
  2. draw the data,
  3. save the figure,
  4. close the figure.

Example:

python
1import matplotlib.pyplot as plt
2
3fig, ax = plt.subplots()
4ax.bar(["A", "B", "C"], [3, 5, 2])
5ax.set_ylabel("Count")
6
7fig.savefig("bars.png", dpi=200, bbox_inches="tight")
8plt.close(fig)

This pattern keeps each output self-contained and reduces bugs caused by leftover global pyplot state.

Common Pitfalls

  • Calling plt.show() before savefig() in an environment where the figure gets cleared afterward.
  • Saving the wrong figure when multiple figures are open.
  • Clearing or closing the plot before the save call.
  • Using an interactive backend in a headless environment.
  • Assuming the file is blank when the real issue is invalid data or invisible axis limits.

Summary

  • A blank image usually means the figure state was empty or the wrong figure was saved.
  • Save before show() if your environment clears figures after display.
  • Prefer fig.savefig() when working with multiple plots.
  • In scripts and CI jobs, a backend such as Agg is often the safest choice.
  • If the file exists but looks empty, verify the plotted data and axis state before blaming savefig().

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.