π¨ Figure Organization: Subplots and Layouts in Matplotlib
The Art Gallery Analogy
Imagine youβre a museum curator arranging paintings on a wall. You have:
- One big wall (the Figure)
- Many paintings to hang (the Subplots/Axes)
- Rules about spacing, sizes, and positions
Matplotlib works the same way! Letβs learn how to create beautiful, organized displays of your data.
πΌοΈ Creating Subplots
Think of subplots() as your painting grid maker. You tell it how many rows and columns you want.
The Simplest Way
import matplotlib.pyplot as plt
# Create 2 rows, 2 columns = 4 paintings
fig, axes = plt.subplots(2, 2)
# axes is now a 2x2 grid!
# axes[0, 0] = top-left
# axes[0, 1] = top-right
# axes[1, 0] = bottom-left
# axes[1, 1] = bottom-right
One Row or One Column
# 3 paintings in a row
fig, axes = plt.subplots(1, 3)
# axes[0], axes[1], axes[2]
# 3 paintings stacked vertically
fig, axes = plt.subplots(3, 1)
# axes[0], axes[1], axes[2]
Key Point: When you have just 1 row or 1 column, axes becomes a simple list!
π Figure Size and DPI
Figure Size = How big is your wall? (in inches) DPI = How detailed is each inch? (dots per inch)
# Make a figure 10 inches wide, 6 inches tall
fig, ax = plt.subplots(figsize=(10, 6))
# High-quality export (300 DPI)
fig, ax = plt.subplots(
figsize=(10, 6),
dpi=300
)
Quick Reference
| figsize | Best For |
|---|---|
| (6, 4) | Default, general use |
| (10, 6) | Presentations |
| (8, 8) | Square plots |
| (12, 4) | Wide panoramic |
Remember: Bigger DPI = Sharper image = Larger file size!
π§Ή Tight Layout
Sometimes paintings overlap their frames. tight_layout() is your automatic spacing fixer.
fig, axes = plt.subplots(2, 2)
# Plot your data...
axes[0, 0].set_title("Sales 2024")
axes[0, 1].set_ylabel("Revenue ($)")
# Fix overlapping labels!
plt.tight_layout()
plt.show()
Before vs After
BEFORE tight_layout(): AFTER tight_layout():
βββββββ¬ββββββ βββββββ¬ββββββ
βTitleβ β βTitleβ β
β getsβ β β β β
β cut β β β β β
βββββββΌββββββ€ βββββββΌββββββ€
β βLabelβ β βLabelβ
β β hid β β β β
βββββββ΄ββββββ βββββββ΄ββββββ
Pro Tip: Add padding with plt.tight_layout(pad=2.0)
ποΈ GridSpec for Layouts
Need paintings of different sizes? GridSpec is your custom frame builder.
import matplotlib.gridspec as gridspec
fig = plt.figure(figsize=(10, 8))
# Create a 3x3 grid
gs = gridspec.GridSpec(3, 3)
# Big painting spanning 2 rows, 2 columns
ax1 = fig.add_subplot(gs[0:2, 0:2])
# Small painting on the right
ax2 = fig.add_subplot(gs[0, 2])
# Another small one below it
ax3 = fig.add_subplot(gs[1, 2])
# Wide painting at bottom
ax4 = fig.add_subplot(gs[2, :])
Visual Map
βββββββββββββ¬ββββββ
β β ax2 β
β ax1 βββββββ€
β β ax3 β
βββββββββββββ΄ββββββ€
β ax4 β
βββββββββββββββββββ
Think of it like Tetris! You choose where each piece goes.
π― Subplot2grid Function
A simpler way to place paintings at exact positions!
fig = plt.figure(figsize=(8, 6))
# subplot2grid((rows, cols), (start_row, start_col))
# Top-left, spans 2 columns
ax1 = plt.subplot2grid(
(3, 3), # 3x3 grid
(0, 0), # Start at row 0, col 0
colspan=2 # Span 2 columns
)
# Top-right
ax2 = plt.subplot2grid(
(3, 3), (0, 2)
)
# Middle-left, spans 2 rows
ax3 = plt.subplot2grid(
(3, 3), (1, 0),
rowspan=2
)
# Bottom-right corner
ax4 = plt.subplot2grid(
(3, 3), (2, 2)
)
Parameters Explained
| Parameter | What it does |
|---|---|
(rows, cols) |
Total grid size |
(row, col) |
Where to start |
colspan |
How many columns wide |
rowspan |
How many rows tall |
β Adding Axes Manually
Sometimes you need total control. Use add_axes() with exact coordinates!
fig = plt.figure(figsize=(8, 6))
# add_axes([left, bottom, width, height])
# Values are fractions from 0 to 1!
# Main plot (most of the space)
main_ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
# Small box in top-right
small_ax = fig.add_axes([0.65, 0.65, 0.2, 0.2])
The Coordinate System
0.0 0.5 1.0
ββββββββββββββββββββββββββββ
1.0 β β
β [0.1, 0.5, 0.3, 0.4]β
0.5 β ββββββββββ β
β β β β
β ββββββββββ β
0.0 ββββββββββββββββββββββββββββ
[left, bottom, width, height]
π Inset Axes
Want a magnifying glass showing zoomed details? Use inset axes!
fig, ax = plt.subplots()
# Plot main data
ax.plot(x, y)
# Create inset (zoomed view)
inset = ax.inset_axes(
[0.6, 0.6, 0.35, 0.35] # position
)
# Plot same data in inset
inset.plot(x, y)
# Zoom to specific region
inset.set_xlim(40, 60)
inset.set_ylim(0.5, 1.5)
# Draw box showing zoomed area
ax.indicate_inset_zoom(inset)
The Result
βββββββββββββββββββββββββββ
β βββββββ
β π Main Plot βzoomββ
β βviewββ
β β βββββββ
β βββββ β
β ββββββ zoomed area β
βββββββββββββββββββββββββββ
Perfect for: Showing fine details in scientific data!
π Subplot Spacing
Control the gaps between paintings with these parameters:
fig, axes = plt.subplots(2, 3)
# Adjust spacing
plt.subplots_adjust(
left=0.1, # Left margin
right=0.9, # Right margin
top=0.9, # Top margin
bottom=0.1, # Bottom margin
wspace=0.3, # Width space between plots
hspace=0.4 # Height space between plots
)
Visual Guide
left=0.1 right=0.9
β β
βΌ βΌ
ββββββββββββββββββββββββββββ β top=0.9
β ββββββ wspace ββββββ β
β β β β0.3β β β β
β ββββββ ββββββ β
β β hspace = 0.4 β
β βΌ β
β ββββββ ββββββ β
β β β β β β
β ββββββ ββββββ β
ββββββββββββββββββββββββββββ β bottom=0.1
Quick Fixes
| Problem | Solution |
|---|---|
| Labels cut off | Increase margins |
| Plots too far apart | Decrease wspace/hspace |
| Plots overlapping | Increase wspace/hspace |
| Need more room | Use tight_layout() |
π Complete Example
Letβs build a dashboard using everything we learned!
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np
# Create figure
fig = plt.figure(figsize=(12, 8), dpi=100)
# Create custom grid
gs = gridspec.GridSpec(
3, 3,
hspace=0.3,
wspace=0.3
)
# Big chart (top-left, 2x2)
ax_main = fig.add_subplot(gs[0:2, 0:2])
ax_main.set_title("Main Chart")
# Side panel 1
ax_side1 = fig.add_subplot(gs[0, 2])
ax_side1.set_title("Detail 1")
# Side panel 2
ax_side2 = fig.add_subplot(gs[1, 2])
ax_side2.set_title("Detail 2")
# Bottom bar (full width)
ax_bottom = fig.add_subplot(gs[2, :])
ax_bottom.set_title("Timeline")
plt.tight_layout()
plt.show()
The Dashboard Layout
ββββββββββββββββββββ¬βββββββββ
β βDetail 1β
β Main Chart ββββββββββ€
β βDetail 2β
ββββββββββββββββββββ΄βββββββββ€
β Timeline β
βββββββββββββββββββββββββββββ
π Key Takeaways
plt.subplots()- Quick grid of equal-sized plotsfigsize&dpi- Control canvas size and qualitytight_layout()- Auto-fix overlapping labelsGridSpec- Complex layouts with different sizessubplot2grid()- Place plots at specific grid positionsadd_axes()- Exact positioning with coordinates- Inset axes - Zoom boxes inside your plot
subplots_adjust()- Fine-tune spacing manually
π¨ Flow Diagram
graph TD A[Start: Need Multiple Plots] --> B{Same Size?} B -->|Yes| C[plt.subplots] B -->|No| D{Complex Layout?} D -->|Simple| E[subplot2grid] D -->|Complex| F[GridSpec] C --> G{Labels Overlap?} E --> G F --> G G -->|Yes| H[tight_layout] G -->|No| I[subplots_adjust] H --> J[Display Plot] I --> J
Now go create beautiful, organized visualizations! π