How to remove gaps between subplots

Learn how to remove gaps between subplots with practical examples, diagrams, and best practices. Covers python, matplotlib, subplot development techniques with visual explanations.

Mastering Matplotlib: Eliminating Gaps Between Subplots

Hero image for How to remove gaps between subplots

Learn how to effectively remove unwanted spacing and gaps between subplots in Matplotlib, creating a clean and professional visualization layout.

When creating multi-panel figures in Matplotlib, it's common to encounter default spacing or 'gaps' between your subplots. While these gaps can sometimes be desirable for readability, there are many scenarios where you need a more compact layout, perhaps to maximize data display or create a seamless visual effect. This article will guide you through various methods to precisely control and eliminate these gaps, ensuring your Matplotlib figures look exactly as intended.

Understanding Subplot Spacing in Matplotlib

Matplotlib provides several mechanisms to manage the layout of subplots within a figure. By default, functions like plt.subplots() or fig.add_subplot() introduce a certain amount of padding between subplots and around the figure edges. This padding is controlled by parameters such as wspace (width space), hspace (height space), left, right, top, and bottom. Understanding how these parameters interact is key to achieving a gap-free layout.

flowchart TD
    A[Start] --> B{Create Figure & Subplots}
    B --> C{Default Spacing Applied}
    C --> D{Need to Remove Gaps?}
    D -- Yes --> E[Adjust Subplot Parameters]
    E --> F{Use `plt.subplots_adjust()`}
    E --> G{Use `fig.tight_layout()`}
    E --> H{Use `GridSpec`}
    F --> I[Achieve Desired Layout]
    G --> I
    H --> I
    D -- No --> I
    I --> J[End]

Decision flow for managing subplot spacing in Matplotlib.

Method 1: Using plt.subplots_adjust()

The plt.subplots_adjust() function (or fig.subplots_adjust() for a specific figure object) offers fine-grained control over subplot spacing. You can specify the wspace and hspace parameters to control the horizontal and vertical spacing between subplots, respectively. Setting these to 0 will effectively remove the gaps. Additionally, you can adjust the left, right, top, and bottom margins of the figure.

import matplotlib.pyplot as plt
import numpy as np

# Create some dummy data
x = np.linspace(0, 2 * np.pi, 400)
y1 = np.sin(x)
y2 = np.cos(x)

# Create a figure with 2x2 subplots
fig, axes = plt.subplots(2, 2, figsize=(8, 6))

# Plot on each subplot
axes[0, 0].plot(x, y1, color='blue')
axes[0, 0].set_title('Sine Wave 1')

axes[0, 1].plot(x, y2, color='red')
axes[0, 1].set_title('Cosine Wave 1')

axes[1, 0].plot(x, y1 + y2, color='green')
axes[1, 0].set_title('Sum Wave 2')

axes[1, 1].plot(x, y1 * y2, color='purple')
axes[1, 1].set_title('Product Wave 2')

# Adjust subplot parameters to remove gaps
plt.subplots_adjust(wspace=0, hspace=0)

# Optional: Remove axis labels/ticks for a cleaner look if desired
for ax in axes.flat:
    ax.set_xticks([])
    ax.set_yticks([])

plt.suptitle('Subplots with No Gaps (subplots_adjust)', y=1.02) # Adjust suptitle position
plt.show()

Using plt.subplots_adjust(wspace=0, hspace=0) to remove spacing between subplots.

Method 2: Leveraging fig.tight_layout()

For a more automated approach, fig.tight_layout() (or plt.tight_layout()) automatically adjusts subplot parameters for a tight layout. It attempts to make the figure fit all labels and titles without overlapping. While it doesn't always result in zero gaps, it often significantly reduces them and is a good first step for general layout optimization. You can pass pad, w_pad, and h_pad arguments to control the padding around the figure and between subplots.

import matplotlib.pyplot as plt
import numpy as np

# Create some dummy data
x = np.linspace(0, 2 * np.pi, 400)
y1 = np.sin(x)
y2 = np.cos(x)

# Create a figure with 2x2 subplots
fig, axes = plt.subplots(2, 2, figsize=(8, 6))

# Plot on each subplot
axes[0, 0].plot(x, y1, color='blue')
axes[0, 0].set_title('Sine Wave 1')

axes[0, 1].plot(x, y2, color='red')
axes[0, 1].set_title('Cosine Wave 1')

axes[1, 0].plot(x, y1 + y2, color='green')
axes[1, 0].set_title('Sum Wave 2')

axes[1, 1].plot(x, y1 * y2, color='purple')
axes[1, 1].set_title('Product Wave 2')

# Use tight_layout to adjust spacing
fig.tight_layout(pad=0.0, w_pad=0.0, h_pad=0.0)

# Optional: Remove axis labels/ticks for a cleaner look if desired
for ax in axes.flat:
    ax.set_xticks([])
    ax.set_yticks([])

plt.suptitle('Subplots with No Gaps (tight_layout)', y=1.02) # Adjust suptitle position
plt.show()

Using fig.tight_layout(pad=0.0, w_pad=0.0, h_pad=0.0) for a compact layout.

Method 3: Advanced Layout with GridSpec

For highly customized subplot arrangements, GridSpec offers the most flexibility. It allows you to define the geometry of the grid that subplots will be placed on, including explicit control over spacing. You can create a GridSpec object and then add subplots to specific cells or ranges of cells within that grid, specifying wspace and hspace directly during its creation.

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.gridspec import GridSpec

# Create some dummy data
x = np.linspace(0, 2 * np.pi, 400)
y1 = np.sin(x)
y2 = np.cos(x)

fig = plt.figure(figsize=(8, 6))

# Create a GridSpec with 2 rows, 2 columns, and no spacing
gs = GridSpec(2, 2, figure=fig, wspace=0, hspace=0)

# Add subplots using the GridSpec
ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1])
ax3 = fig.add_subplot(gs[1, 0])
ax4 = fig.add_subplot(gs[1, 1])

# Plot on each subplot
ax1.plot(x, y1, color='blue')
ax1.set_title('Sine Wave 1')

ax2.plot(x, y2, color='red')
ax2.set_title('Cosine Wave 1')

ax3.plot(x, y1 + y2, color='green')
ax3.set_title('Sum Wave 2')

ax4.plot(x, y1 * y2, color='purple')
ax4.set_title('Product Wave 2')

# Optional: Remove axis labels/ticks for a cleaner look if desired
for ax in [ax1, ax2, ax3, ax4]:
    ax.set_xticks([])
    ax.set_yticks([])

plt.suptitle('Subplots with No Gaps (GridSpec)', y=1.02) # Adjust suptitle position
plt.show()

Using GridSpec to define a subplot layout with zero spacing.

Combining Techniques and Best Practices

Often, the best approach involves a combination of these methods. For instance, you might start with plt.subplots() for convenience, then use plt.subplots_adjust() to fine-tune the spacing. For very complex layouts, GridSpec provides the ultimate control. Remember to consider the overall aesthetic of your plot: sometimes a small amount of padding improves readability, especially if titles or labels are present.

1. Create your initial subplots

Start by generating your figure and subplots using plt.subplots(rows, cols) or by adding subplots to a figure using fig.add_subplot().

2. Plot your data

Populate each subplot with your desired data, titles, and labels.

3. Choose your spacing adjustment method

Decide whether plt.subplots_adjust(), fig.tight_layout(), or GridSpec is most appropriate for your specific layout needs. For simple cases, subplots_adjust(wspace=0, hspace=0) is often sufficient.

4. Refine and review

After applying the spacing adjustments, review your figure. You might need to remove axis ticks or labels (ax.set_xticks([]), ax.set_yticks([])) or adjust suptitle position (plt.suptitle(..., y=...)) to prevent overlap, especially when gaps are completely removed.