Subplots and Layouts

Loading concept...

🎨 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

  1. plt.subplots() - Quick grid of equal-sized plots
  2. figsize & dpi - Control canvas size and quality
  3. tight_layout() - Auto-fix overlapping labels
  4. GridSpec - Complex layouts with different sizes
  5. subplot2grid() - Place plots at specific grid positions
  6. add_axes() - Exact positioning with coordinates
  7. Inset axes - Zoom boxes inside your plot
  8. 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! πŸš€

Loading story...

No Story Available

This concept doesn't have a story yet.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Interactive Preview

Interactive - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Interactive Content

This concept doesn't have interactive content yet.

Cheatsheet Preview

Cheatsheet - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Cheatsheet Available

This concept doesn't have a cheatsheet yet.

Quiz Preview

Quiz - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Quiz Available

This concept doesn't have a quiz yet.