Skip to content

Matplotlib - Multiplots

Matplotlib - Creating Multiple Plots (Subplots)

Section titled “Matplotlib - Creating Multiple Plots (Subplots)”

Often, you need to display multiple plots together within a single figure canvas. Matplotlib provides several ways to achieve this, allowing you to create grids of plots or place plots in custom locations.

This is the most convenient and recommended function for creating a regular grid of subplots. It creates both the Figure and a NumPy array of Axes objects in one call.

plt.subplots(nrows=1, ncols=1, ...)

Arguments nrows and ncols define the grid dimensions. The function returns a tuple: (figure, axes). axes is either a single Axes object (for a 1x1 grid) or a NumPy array of Axes objects.

import matplotlib.pyplot as plt
import numpy as np
# Create a figure and a 2x2 grid of Axes objects
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(8, 8), layout='constrained')
# Data for plotting
x = np.linspace(0, 2 * np.pi, 100)
# Access individual Axes using array indexing
axes[0, 0].plot(x, np.sin(x), 'r-')
axes[0, 0].set_title('Top Left (Sine)')
axes[0, 1].plot(x, np.cos(x), 'g--')
axes[0, 1].set_title('Top Right (Cosine)')
axes[1, 0].plot(x, np.tan(x), 'b.')
axes[1, 0].set_title('Bottom Left (Tangent)')
axes[1, 0].set_ylim(-5, 5) # Limit y for tan
axes[1, 1].plot(x, np.exp(-x), 'k:')
axes[1, 1].set_title('Bottom Right (Exponential Decay)')
# Add a main title to the Figure
fig.suptitle('Example 2x2 Subplots', fontsize=16)
# Adjust layout automatically (alternative to layout='constrained' in subplots)
# plt.tight_layout(rect=[0, 0, 1, 0.96]) # rect adjusts for suptitle
plt.show()

This code creates a figure containing four plots arranged in a 2x2 grid. Each plot is created by calling methods on the corresponding Axes object within the axes array.

This method is part of the object-oriented API and adds a single subplot to an existing Figure (fig). You specify the grid geometry and the index of the subplot to create.

fig = plt.figure()
ax1 = fig.add_subplot(nrows, ncols, index)
# index goes from 1 to nrows * ncols, row by row

A shorthand notation fig.add_subplot(221) is equivalent to fig.add_subplot(2, 2, 1).

Example: Overlapping Subplots (Less Common)

Section titled “Example: Overlapping Subplots (Less Common)”

While plt.subplots manages non-overlapping plots well, add_subplot can technically create overlapping plots if called with conflicting indices, though this is usually not desired.

fig = plt.figure(figsize=(6, 4))
# Add first subplot (whole figure area)
ax1 = fig.add_subplot(1, 1, 1)
ax1.plot([1, 2, 3], [1, 2, 3], 'r-')
ax1.set_title('Axes 1 (Full)')
# Add second subplot (top-left quadrant), potentially overlapping ax1 content
ax2 = fig.add_subplot(2, 2, 1, facecolor='lightblue') # 2x2 grid, 1st plot
ax2.plot([1, 2, 3], [3, 2, 1], 'b--')
ax2.set_title('Axes 2 (Top-Left)')
plt.show()

This shows how add_subplot adds Axes individually. Using it carefully allows creating complex layouts not possible with a simple grid.

3. Using fig.add_axes() for Custom Placement (Inset Plots)

Section titled “3. Using fig.add_axes() for Custom Placement (Inset Plots)”

For complete control over subplot position and size, use fig.add_axes([left, bottom, width, height]). The coordinates are fractions of the Figure dimensions.

import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2 * np.pi, 200)
fig = plt.figure(figsize=(8, 5))
# Main axes
ax_main = fig.add_axes([0.1, 0.1, 0.8, 0.8])
ax_main.plot(x, np.sin(x), 'b-')
ax_main.set_title('Main Plot (Sine)')
ax_main.set_xlabel('X')
ax_main.set_ylabel('sin(x)')
# Inset axes
ax_inset = fig.add_axes([0.6, 0.6, 0.25, 0.25]) # Position: [left, bottom, width, height]
ax_inset.plot(x, np.cos(x), 'r--')
ax_inset.set_title('Inset Plot (Cosine)')
ax_inset.set_xticks([]) # Hide ticks for smaller plot if desired
ax_inset.set_yticks([])
plt.show()

This creates a main plot showing a sine wave and a smaller inset plot showing a cosine wave, positioned within the upper-right area of the main plot. add_axes is ideal for such custom layouts.

Choose the method that best suits your layout needs: plt.subplots() for regular grids, fig.add_subplot() for potentially complex grid-based layouts built step-by-step, and fig.add_axes() for precise, arbitrary placement.