Improve subplot size/spacing with many subplots
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
When creating figures with many subplots in matplotlib, the default spacing often causes overlapping titles, labels, and tick marks. Matplotlib provides several tools to control subplot size and spacing: plt.tight_layout() for automatic adjustment, plt.subplots_adjust() for manual control, GridSpec for advanced layouts, and constrained_layout for a modern automatic approach.
The Problem: Default Spacing
Method 1: tight_layout() (Simplest)
plt.tight_layout() automatically adjusts subplot spacing to prevent overlap:
Add padding between subplots:
Method 2: subplots_adjust() (Manual Control)
For precise control over all spacing parameters:
| Parameter | What it controls | Default |
left | Left margin | 0.125 |
right | Right margin | 0.9 |
top | Top margin | 0.88 |
bottom | Bottom margin | 0.11 |
wspace | Horizontal gap between subplots | 0.2 |
hspace | Vertical gap between subplots | 0.2 |
Method 3: constrained_layout (Modern)
constrained_layout is a newer alternative to tight_layout that handles more edge cases, including colorbars and legends:
Enable it globally:
Method 4: GridSpec (Advanced Layouts)
GridSpec gives full control over subplot sizes and positions:
Subplots of Different Sizes
Method 5: Increase Figure Size
Sometimes the simplest fix is making the figure larger:
A good rule of thumb: allocate at least 3-4 inches per subplot in each dimension.
Removing Redundant Labels
When subplots share axes, remove inner labels to save space:
Suptitle with Subplots
fig.suptitle() often overlaps the top row. Fix with top parameter:
Common Pitfalls
- tight_layout() after all content is added: Call
plt.tight_layout()after all subplots, titles, labels, and legends are set. Calling it too early means it calculates spacing without accounting for later additions. - constrained_layout + tight_layout conflict: Do not use both. They are mutually exclusive approaches. If
constrained_layout=Trueis set, do not calltight_layout(). - Colorbars with tight_layout:
tight_layout()does not account for colorbars well. Useconstrained_layout=Trueinstead, or manually adjust withsubplots_adjust(). - DPI and saved figure size: The spacing that looks good on screen may look different when saved at high DPI. Always check the saved output with
plt.savefig('plot.png', dpi=150, bbox_inches='tight'). - Too many subplots: Beyond ~25 subplots (5x5), individual plots become too small to read regardless of spacing. Consider paginating across multiple figures or using a different visualization approach.
Summary
- Use
plt.tight_layout()as the first fix for overlapping labels — it handles most cases - Use
constrained_layout=Truefor figures with colorbars, legends, or complex elements - Use
fig.subplots_adjust(wspace=, hspace=)for manual fine-tuning of spacing - Use
GridSpecfor non-uniform subplot sizes and advanced layouts - Use
sharex=True, sharey=Truewithlabel_outer()to eliminate redundant tick labels - Increase
figsizeto give each subplot more room — sometimes the simplest solution

