Choosing Between tight_layout and constrained_layout in Matplotlib for Clean Blog Figures
Learn how to pick tight_layout vs constrained_layout in Matplotlib to avoid overlapping subplots and excess whitespace in blog figures.
21 Jun 2026, 08:49 UTC

The problem that makes blog figures look messy
When you place several subplots in a figure, the default spacing often leads to overlapping labels or large empty margins. The result is a cluttered image that distracts readers and wastes space in a blog post.
tight_layout: the classic automatic spacer
Introduced in Matplotlib 2.0, tight_layout automatically adjusts subplot parameters so that axes, labels, and titles do not overlap. You call it after creating the figure:
import matplotlib.pyplot as plt
fig, axs = plt.subplots(2, 2)
for ax in axs.flat:
ax.plot([0, 1], [0, 1])
fig.tight_layout()
plt.show()
It works well for simple figures and requires no extra arguments. However, it only considers the rendered text size, so complex arrangements—especially those with a suptitle or merged cells—may still leave unwanted gaps.
constrained_layout: the newer constraint‑solving engine
Starting with Matplotlib 3.4, constrained_layout replaces the older algorithm with a constraint‑solving approach. It treats the entire figure as a set of mathematical constraints and finds an optimal arrangement automatically. Example:
import matplotlib.pyplot as plt
fig, axs = plt.subplots(2, 2, constrained_layout=True)
for ax in axs.flat:
ax.plot([0, 1], [0, 1])
fig.suptitle('Demo')
plt.show()
Because it solves a system of equations, the layout often reduces white space more aggressively than tight_layout, especially when a suptitle is present.
Side‑by‑side comparison
Below is a minimal script that creates the same four‑panel figure with both layout methods. Run it with a recent Matplotlib (≥3.4) to see the difference.
import matplotlib.pyplot as plt
# data
x = [0, 1, 2]
y1 = [0, 1, 0]
y2 = [0, 0, 1]
fig1, axs1 = plt.subplots(2, 2)
for ax, y in zip(axs1.flat, [y1, y2, y1, y2]):
ax.plot(x, y)
fig1.tight_layout()
fig1.savefig('tight.png')
fig2, axs2 = plt.subplots(2, 2, constrained_layout=True)
for ax, y in zip(axs2.flat, [y1, y2, y1, y2]):
ax.plot(x, y)
fig2.suptitle('Demo')
fig2.savefig('constrained.png')
After saving the two PNG files, open them side by side. The constrained.png typically shows tighter margins and more content per inch, while tight.png may have larger blank areas, especially at the top where the suptitle sits.
Trade‑off and practical considerations
- Compatibility:
tight_layoutworks back to Matplotlib 2.0, making it safe for older environments.constrained_layoutis unavailable before version 3.4 and will raise an error if used on older releases. - Performance: The constraint solver adds a small computation overhead. For typical blog figures (under a few hundred elements) the delay is imperceptible, but very large figures with thousands of artists may see a noticeable pause.
- Fine‑tuning: Even with
constrained_layout, complex grids with merged cells can still need manualsubplots_adjusttweaks to resolve stubborn overlaps.
When to use which layout
If your blog targets modern browsers and you can require Matplotlib 3.4 or newer, adopt constrained_layout as the default. It gives cleaner, more responsive figures with minimal manual tweaking. For projects that must support older installations or where performance is critical, keep tight_layout as a fallback and test the output before publishing.
Actionable closing
Check your Matplotlib version, choose the appropriate layout, and verify the result by comparing the generated images. For most current blog workflows, the recommendation is:
- Run
import matplotlib; print(matplotlib.__version__)to confirm ≥3.4. - Use
constrained_layout=Truewhen creating subplots, or setfig.constrained_layout = Truefor the whole figure. - Generate the figure, save it, and visually inspect that margins are reduced compared to a
tight_layoutversion.
Following these steps will give your readers crisp, professional‑looking plots without the need for extensive manual spacing adjustments.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.