Skip to main content

Python Matplotlib: How to Clear and Close Matplotlib Figures in Python

Managing figure lifecycles in Matplotlib prevents memory leaks and ensures your plots render correctly. Understanding the difference between cla(), clf(), and close() is essential when creating multiple visualizations, especially in loops or long-running applications.

Understanding the Matplotlib Hierarchy

Matplotlib organizes visual elements in a three-level hierarchy, and each clearing method operates at a different level:

Figure (the window/canvas)
└── Axes (individual subplot)
└── Artists (lines, text, patches)
MethodTarget LevelWhat It Does
cla()AxesClears single subplot, preserves figure structure
clf()FigureRemoves all subplots, keeps window open
close()SystemDestroys figure completely, releases memory

Using cla() to Clear a Single Subplot

The cla() method clears the current axes (subplot) while maintaining the figure layout. This is useful for real-time updates or redrawing specific panels in a dashboard.

import matplotlib.pyplot as plt
import numpy as np

# Create a figure with two subplots
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))

# Plot initial data
ax1.plot([1, 2, 3, 4], [1, 4, 2, 3], 'b-', label='Original')
ax1.set_title('Left Panel')
ax1.legend()

ax2.plot([1, 2, 3, 4], [3, 1, 4, 2], 'r-', label='Data')
ax2.set_title('Right Panel')
ax2.legend()

plt.tight_layout()
plt.savefig('before_cla.png')

# Clear only the left subplot
ax1.cla()

# Redraw with new data: ax2 remains unchanged
ax1.plot([1, 2, 3, 4], [4, 3, 2, 1], 'g--', label='New Data')
ax1.set_title('Refreshed Left Panel')
ax1.legend()

plt.savefig('after_cla.png')
plt.show()
tip

After calling cla(), you need to reapply axis labels, titles, and legends since these are considered part of the axes content.

Real-Time Animation Example

import matplotlib.pyplot as plt
import numpy as np
import time

fig, ax = plt.subplots()
plt.ion() # Enable interactive mode

for frame in range(50):
ax.cla() # Clear previous frame

# Generate new data
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x + frame * 0.1)

ax.plot(x, y, 'b-')
ax.set_ylim(-1.5, 1.5)
ax.set_title(f'Frame {frame}')

plt.pause(0.05)

plt.ioff()
plt.show()

Using clf() to Reset the Entire Figure

The clf() method clears the entire figure, removing all subplots and content while keeping the figure window open. Use this when you want to completely redesign a figure's layout.

import matplotlib.pyplot as plt
import numpy as np

# Create initial plot
plt.figure(figsize=(8, 6))
plt.subplot(2, 2, 1)
plt.plot([1, 2, 3], [1, 2, 3])
plt.subplot(2, 2, 2)
plt.plot([1, 2, 3], [3, 2, 1])
plt.suptitle('Original Layout')
plt.savefig('before_clf.png')

# Clear everything and start fresh
plt.clf()

# Create completely different layout
plt.subplot(1, 1, 1) # Single plot instead of 2x2
x = np.linspace(0, 10, 100)
plt.plot(x, np.sin(x), 'r-', linewidth=2)
plt.title('Fresh Start - New Layout')
plt.xlabel('X axis')
plt.ylabel('Y axis')

plt.savefig('after_clf.png')
plt.show()

Comparing cla() and clf()

import matplotlib.pyplot as plt

fig, (ax1, ax2) = plt.subplots(1, 2)

ax1.plot([1, 2, 3])
ax2.plot([3, 2, 1])

# Using cla(): clears ax1 only, ax2 and layout preserved
ax1.cla()
print(f"After cla(): Figure has {len(fig.axes)} axes")

# Using clf(): removes everything
plt.clf()
print(f"After clf(): Figure has {len(fig.axes)} axes")

Output:

After cla(): Figure has 2 axes
After clf(): Figure has 0 axes

Using close() to Release Memory

The close() function destroys a figure completely, releasing all associated memory. This is critical for batch processing and long-running scripts.

import matplotlib.pyplot as plt
import numpy as np

def generate_report_pages(data_list, output_dir):
"""Generate multiple plot files without memory leaks."""

for i, data in enumerate(data_list):
# Create a new figure for each page
fig, ax = plt.subplots(figsize=(8, 6))

ax.plot(data['x'], data['y'])
ax.set_title(data['title'])
ax.set_xlabel('X')
ax.set_ylabel('Y')

# Save to file
filepath = f"{output_dir}/page_{i:03d}.png"
plt.savefig(filepath, dpi=150, bbox_inches='tight')

# Critical: release memory
plt.close(fig)

print(f"Generated {len(data_list)} pages")


# Example usage
data_list = [
{'x': range(10), 'y': [i**2 for i in range(10)], 'title': f'Chart {n}'}
for n in range(100)
]

generate_report_pages(data_list, './output')
caution

Without plt.close(), each iteration creates a new figure that remains in memory. Processing hundreds of plots without closing them can consume gigabytes of RAM and eventually crash your program.

Different Ways to Close Figures

import matplotlib.pyplot as plt

# Create multiple figures
fig1 = plt.figure(num='First')
fig2 = plt.figure(num='Second')
fig3 = plt.figure(num=3)

# Close by figure object
plt.close(fig1)

# Close by figure number or name
plt.close('Second')
plt.close(3)

# Close the current active figure
plt.figure()
plt.plot([1, 2, 3])
plt.close() # Closes the most recent figure

# Nuclear option: close everything
plt.figure()
plt.figure()
plt.figure()
print(f"Open figures: {plt.get_fignums()}")

plt.close('all')
print(f"After close('all'): {plt.get_fignums()}")

Output:

Open figures: [1, 2, 3]
After close('all'): []

Memory Management Best Practices

Batch Processing Template

import matplotlib.pyplot as plt
import numpy as np

def create_batch_plots(n_plots):
"""Safely generate multiple plots."""

for i in range(n_plots):
try:
fig, ax = plt.subplots()

# Your plotting code
x = np.random.randn(100)
ax.hist(x, bins=20)
ax.set_title(f'Distribution {i}')

plt.savefig(f'hist_{i:04d}.png')

finally:
# Always close, even if an error occurs
plt.close(fig)


create_batch_plots(50)

Using Context Manager Pattern

import matplotlib.pyplot as plt
from contextlib import contextmanager

@contextmanager
def managed_figure(*args, **kwargs):
"""Context manager for automatic figure cleanup."""
fig = plt.figure(*args, **kwargs)
try:
yield fig
finally:
plt.close(fig)


# Usage
for i in range(100):
with managed_figure(figsize=(8, 6)) as fig:
ax = fig.add_subplot(111)
ax.plot([1, 2, 3], [i, i*2, i*3])
plt.savefig(f'managed_{i:03d}.png')
# Figure automatically closed here

Quick Reference

ScenarioMethodExample
Update single subplotax.cla()Real-time sensor display
Reset figure layoutplt.clf()Interactive dashboard refresh
Batch file generationplt.close(fig)Report generation scripts
End of script cleanupplt.close('all')Notebook cells, test teardown
Animation framesax.cla()Live data visualization
info

In Jupyter notebooks, figures display automatically and are usually garbage collected between cells. However, explicitly calling plt.close() is still recommended when generating many figures in a single cell.

Understanding when to use each method ensures your visualizations render correctly while keeping memory usage under control: this is especially important in production environments and data pipelines.