๐Ÿ€Zerve chosen as NCAA's Agentic Data Platform for 2026 Hackathonยท๐ŸงฎMeet the Zerve Team at Data Decoded Londonยท๐Ÿ“ˆWe're hiring โ€” awesome new roles just gone live!
Back
Visualization

ValueError: Empty Figure - How to Fix It

Answer

This error means you're trying to save or display a figure that has no content. Fix it by ensuring you actually plot something before calling savefig() or show(), and that you're referencing the correct figure or axes object.

Why This Happens

You created a figure but didn't add any plots, or you're saving a different figure than the one you drew on. Common causes: calling plt.savefig() after plt.show() (which clears the figure), using object-oriented syntax but saving with plt functions, or plotting to axes that aren't connected to the figure you're saving.

Solution

The rule: plot before save, save before show. Use object-oriented style (fig, ax) to keep track of which figure you're working with. Check that your data isn't empty.

import matplotlib.pyplot as plt
import numpy as np

# โŒ Problematic: savefig after show (figure is cleared)
plt.plot([1, 2, 3], [1, 4, 9])
plt.show()
plt.savefig('plot.png')
# ValueError: empty figure or figure with no content

# โœ… Fixed: save before show
plt.plot([1, 2, 3], [1, 4, 9])
plt.savefig('plot.png')
plt.show()

# โŒ Problematic: forgot to actually plot
fig, ax = plt.subplots()
# forgot ax.plot(...)
fig.savefig('plot.png')
# ValueError: empty figure

# โœ… Fixed: add content to the axes
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [1, 4, 9])
fig.savefig('plot.png')

# โŒ Problematic: plotting to wrong figure
fig1, ax1 = plt.subplots()
fig2, ax2 = plt.subplots()
ax1.plot([1, 2, 3])
fig2.savefig('plot.png')  # fig2 is empty!

# โœ… Fixed: save the correct figure
fig1.savefig('plot.png')

# โŒ Problematic: data is empty
data = []
plt.plot(data)
plt.savefig('plot.png')
# May produce empty figure warning

# โœ… Fixed: check data before plotting
data = [1, 2, 3]
if len(data) > 0:
    plt.plot(data)
    plt.savefig('plot.png')

# โœ… Debug: check what's in the figure
fig, ax = plt.subplots()
ax.plot([1, 2, 3])
print(f"Number of axes: {len(fig.axes)}")
print(f"Lines in ax: {len(ax.lines)}")

# โœ… Clear pattern: create, plot, save, close
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [1, 4, 9])
ax.set_title('My Plot')
fig.savefig('plot.png', dpi=150)
plt.close(fig)

Better Workflow

Zerve captures every figure when the block completes, automatically. No plt.show(), no plt.savefig(), no blank-image traps. Figures live in the block output. Each block has one figure, one reference. No plt.gca() surprises from stale references. If your data is empty, you see it in the previous block before you even try to plot. Just plot it. Zerve handles the rest. No show, no save, no drama.

Better workflow

Related Topics

Decision-grade data work

Explore, analyze and deploy your first project in minutes