Python
Matplotlib
Data Visualization
Subplots
Plotting Techniques

Matplotlib different size subplots

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Matplotlib makes equal-sized subplot grids easy with plt.subplots(), but real dashboards often need one chart to be larger than the others. The usual solution is to move from the simple grid helper to GridSpec or the newer subplot layout APIs that let axes span multiple rows or columns. Once you think in terms of grid cells instead of subplot indices, uneven layouts become straightforward.

Use GridSpec for Uneven Layouts

GridSpec lets you define a grid and then decide how many rows and columns each subplot should occupy.

python
1import matplotlib.pyplot as plt
2import numpy as np
3
4fig = plt.figure(figsize=(10, 6))
5gs = fig.add_gridspec(2, 3)
6
7ax_main = fig.add_subplot(gs[:, :2])
8ax_top_right = fig.add_subplot(gs[0, 2])
9ax_bottom_right = fig.add_subplot(gs[1, 2])
10
11x = np.linspace(0, 10, 200)
12ax_main.plot(x, np.sin(x))
13ax_main.set_title("Main Plot")
14
15ax_top_right.hist(np.random.randn(500), bins=20)
16ax_top_right.set_title("Histogram")
17
18ax_bottom_right.scatter(np.random.rand(30), np.random.rand(30))
19ax_bottom_right.set_title("Scatter")
20
21fig.tight_layout()
22plt.show()

Here the main plot spans both rows and the first two columns, while the two smaller plots stack on the right.

Control Relative Sizes With Ratios

Sometimes you do not need spanning, only different relative widths or heights. width_ratios and height_ratios control that.

python
1fig = plt.figure(figsize=(10, 6))
2gs = fig.add_gridspec(
3    2,
4    2,
5    width_ratios=[3, 1],
6    height_ratios=[2, 1],
7)
8
9ax1 = fig.add_subplot(gs[0, 0])
10ax2 = fig.add_subplot(gs[0, 1])
11ax3 = fig.add_subplot(gs[1, :])
12
13ax1.set_title("Wide")
14ax2.set_title("Narrow")
15ax3.set_title("Full Width Bottom")
16
17fig.tight_layout()
18plt.show()

This is useful when every subplot should still occupy its own cell, but some columns or rows should be visually larger.

subplot_mosaic for Readable Named Layouts

For dashboards, subplot_mosaic can be more readable than integer slices because you describe the layout with names.

python
1fig, axes = plt.subplot_mosaic(
2    [
3        ["main", "main", "side1"],
4        ["main", "main", "side2"],
5    ],
6    figsize=(10, 6),
7    constrained_layout=True,
8)
9
10axes["main"].plot([1, 2, 3], [2, 3, 5])
11axes["main"].set_title("Main")
12axes["side1"].bar(["A", "B", "C"], [3, 5, 2])
13axes["side2"].plot([1, 2, 3], [5, 3, 4])
14
15plt.show()

This API is especially nice when you want the code to mirror the visual layout conceptually.

Spacing Still Matters

Uneven subplot sizes are only half the problem. Labels, titles, and colorbars can still overlap if spacing is not handled well.

Two common tools are:

  • 'fig.tight_layout()'
  • 'constrained_layout=True'

If the figure has a complicated layout, prefer one consistent spacing strategy instead of stacking several manual adjustments on top of each other.

Start With the Layout, Then Plot

A practical habit is to design the subplot geometry before writing the plotting details. Decide which chart should dominate, which panels are secondary, and whether ratios or spanning communicate that priority better.

Doing that first usually leads to cleaner code than drawing several equal subplots and then retrofitting the layout afterward.

A Good Mental Model

The simplest way to design different-sized subplots is:

  1. decide on an invisible grid
  2. decide which axes span multiple cells
  3. adjust width and height ratios if needed
  4. clean up spacing last

That sequence is easier than starting from subplot indices and trying to patch the layout afterward.

Common Pitfalls

  • Using plt.subplots() and expecting different-sized axes without a custom grid system.
  • Forgetting that GridSpec indexing is zero-based and slice-based.
  • Mixing tight_layout() and heavy manual spacing adjustments until the figure becomes harder to control.
  • Creating a visually complex layout before deciding the underlying grid structure.
  • Ignoring width_ratios and height_ratios when simple proportional sizing would solve the problem.

Summary

  • Use GridSpec or related layout APIs when subplots need different sizes.
  • Let larger axes span multiple grid cells instead of fighting plt.subplots().
  • Use width and height ratios for proportional sizing.
  • Consider subplot_mosaic when named layouts are easier to read.
  • Handle spacing explicitly so the final figure stays readable.

Course illustration
Course illustration

All Rights Reserved.