matplotlib
python
plotting
data visualization
plot management

How do I create a second new plot, then later plot on the old one?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In matplotlib, each plot lives in a Figure object. To create multiple plots and switch between them, you create separate figure references with plt.figure() and use plt.figure(fig_number) to switch back to an earlier figure. The object-oriented API (fig, ax = plt.subplots()) is the cleaner approach — you work directly with figure and axes objects instead of relying on matplotlib's implicit "current figure" state.

The Problem

python
1import matplotlib.pyplot as plt
2
3plt.plot([1, 2, 3], [1, 4, 9])    # Plot on figure 1
4plt.plot([1, 2, 3], [1, 2, 3])    # This adds to figure 1, not a new figure
5
6plt.show()
7# Both lines appear on the same plot — how do you put them on separate plots?

Method 1: plt.figure() with Figure Numbers (State-Based)

python
1import matplotlib.pyplot as plt
2
3# Create figure 1
4plt.figure(1)
5plt.plot([1, 2, 3], [1, 4, 9], 'r-')
6plt.title("Quadratic")
7
8# Create figure 2
9plt.figure(2)
10plt.plot([1, 2, 3], [1, 2, 3], 'b-')
11plt.title("Linear")
12
13# Go back to figure 1 and add more data
14plt.figure(1)
15plt.plot([1, 2, 3], [1, 8, 27], 'g--')
16plt.legend(["x²", "x³"])
17
18plt.show()
19# Two separate windows: figure 1 has two lines, figure 2 has one

plt.figure(n) creates a new figure if number n does not exist, or switches to it if it does.

python
1import matplotlib.pyplot as plt
2
3# Create two separate figures with their axes
4fig1, ax1 = plt.subplots()
5fig2, ax2 = plt.subplots()
6
7# Plot on figure 1
8ax1.plot([1, 2, 3], [1, 4, 9], 'r-')
9ax1.set_title("Quadratic")
10
11# Plot on figure 2
12ax2.plot([1, 2, 3], [1, 2, 3], 'b-')
13ax2.set_title("Linear")
14
15# Go back to figure 1 and add more data — just use ax1
16ax1.plot([1, 2, 3], [1, 8, 27], 'g--')
17ax1.legend(["x²", "x³"])
18
19plt.show()

With the OO API, you hold references to axes objects and plot on them directly. No need to track figure numbers or worry about which figure is "current."

Method 3: Subplots in One Figure

If you want multiple plots in the same window:

python
1import matplotlib.pyplot as plt
2import numpy as np
3
4x = np.linspace(0, 2 * np.pi, 100)
5
6fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
7
8ax1.plot(x, np.sin(x), 'r-')
9ax1.set_title("Sine")
10
11ax2.plot(x, np.cos(x), 'b-')
12ax2.set_title("Cosine")
13
14# Later, add to the first subplot
15ax1.plot(x, np.sin(2 * x), 'r--', alpha=0.5)
16ax1.legend(["sin(x)", "sin(2x)"])
17
18plt.tight_layout()
19plt.show()

Method 4: Grid of Subplots

python
1import matplotlib.pyplot as plt
2import numpy as np
3
4x = np.linspace(0, 10, 100)
5
6fig, axes = plt.subplots(2, 2, figsize=(10, 8))
7
8axes[0, 0].plot(x, np.sin(x))
9axes[0, 0].set_title("sin(x)")
10
11axes[0, 1].plot(x, np.cos(x))
12axes[0, 1].set_title("cos(x)")
13
14axes[1, 0].plot(x, np.exp(-x))
15axes[1, 0].set_title("exp(-x)")
16
17axes[1, 1].plot(x, np.log(x + 1))
18axes[1, 1].set_title("log(x+1)")
19
20# Add to the first subplot later
21axes[0, 0].axhline(y=0, color='gray', linestyle='--')
22
23plt.tight_layout()
24plt.show()

Saving Figures Separately

python
1fig1, ax1 = plt.subplots()
2ax1.plot([1, 2, 3], [1, 4, 9])
3ax1.set_title("Plot A")
4
5fig2, ax2 = plt.subplots()
6ax2.plot([1, 2, 3], [3, 2, 1])
7ax2.set_title("Plot B")
8
9# Save each figure to a different file
10fig1.savefig("plot_a.png", dpi=150, bbox_inches='tight')
11fig2.savefig("plot_b.png", dpi=150, bbox_inches='tight')
12
13# Close figures to free memory
14plt.close(fig1)
15plt.close(fig2)

Using plt.gcf() and plt.gca()

python
1# gcf() = Get Current Figure
2# gca() = Get Current Axes
3
4plt.figure(1)
5plt.plot([1, 2], [1, 2])
6
7plt.figure(2)
8plt.plot([1, 2], [2, 1])
9
10# Switch back to figure 1
11plt.figure(1)
12current_fig = plt.gcf()   # Returns figure 1
13current_ax = plt.gca()    # Returns axes of figure 1
14current_ax.set_xlabel("X axis")

gcf() and gca() are useful in interactive sessions but should be avoided in scripts — use explicit figure/axes references instead.

Real-World Example: Dashboard

python
1import matplotlib.pyplot as plt
2import numpy as np
3
4# Create a dashboard with different plot types
5fig, axes = plt.subplots(2, 2, figsize=(12, 10))
6
7months = ['Jan', 'Feb', 'Mar', 'Apr', 'May']
8revenue = [10, 15, 13, 18, 20]
9costs = [8, 10, 11, 12, 14]
10
11# Bar chart
12axes[0, 0].bar(months, revenue, color='steelblue')
13axes[0, 0].set_title("Monthly Revenue")
14
15# Line chart
16axes[0, 1].plot(months, revenue, 'g-o', label="Revenue")
17axes[0, 1].plot(months, costs, 'r-o', label="Costs")
18axes[0, 1].legend()
19axes[0, 1].set_title("Revenue vs Costs")
20
21# Pie chart
22axes[1, 0].pie([30, 25, 20, 15, 10],
23               labels=['A', 'B', 'C', 'D', 'E'],
24               autopct='%1.0f%%')
25axes[1, 0].set_title("Market Share")
26
27# Scatter plot
28x = np.random.randn(50)
29y = x + np.random.randn(50) * 0.5
30axes[1, 1].scatter(x, y, alpha=0.6)
31axes[1, 1].set_title("Correlation")
32
33plt.suptitle("Q1 Dashboard", fontsize=14)
34plt.tight_layout()
35plt.show()

Common Pitfalls

  • Forgetting plt.figure(n) before plotting: Without switching figures, all plots go on the current (last created) figure. Use the OO API to avoid this entirely.
  • plt.show() clears state: After plt.show(), the current figure is reset. Save references before calling plt.show(), or save figures to files beforehand.
  • Memory leaks: Creating many figures without closing them leaks memory. Use plt.close(fig) or plt.close('all') when done.
  • Jupyter vs scripts: In Jupyter, each cell typically renders automatically with %matplotlib inline. In scripts, you must call plt.show() explicitly. Multiple plt.show() calls block execution until each window is closed.
  • plt.subplot() vs plt.subplots(): plt.subplot(2,2,1) is the old state-based API. fig, axes = plt.subplots(2,2) is the modern OO approach — prefer it.

Summary

  • Use fig, ax = plt.subplots() to create figures and hold references (OO API)
  • Plot on any axes at any time with ax.plot() — no need to switch figures
  • Use plt.figure(n) to switch between figures in the state-based API
  • Use fig, axes = plt.subplots(rows, cols) for multiple plots in one window
  • Save figures with fig.savefig() and close with plt.close(fig) to free memory
  • Prefer the object-oriented API over the state-based plt.plot() approach

Course illustration
Course illustration

All Rights Reserved.