How to remove gaps between subplots
Categories:
Mastering Matplotlib: Eliminating 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.
subplots_adjust()
, remember that wspace
and hspace
are fractions of the average width/height of the subplots, not absolute units. Setting them to 0
means no space at all.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.
tight_layout()
can sometimes cause labels or titles to overlap if there isn't enough space. You might need to manually adjust pad
values or use subplots_adjust()
for more precise control in such cases.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.
GridSpec
is particularly powerful when you need subplots of different sizes or spanning multiple rows/columns, while still maintaining precise control over 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.