Bird
Raised Fist0
Matplotlibdata~15 mins

Plt.subplots with rows and columns in Matplotlib - Deep Dive

Choose your learning style10 modes available
Overview - Plt.subplots with rows and columns
What is it?
Plt.subplots is a function in matplotlib that creates a grid of plots (called subplots) arranged in rows and columns. It returns a figure object and an array of axes objects, where each axis is a place to draw a plot. This helps organize multiple charts neatly in one window. You can specify how many rows and columns you want to arrange your plots in.
Why it matters
Without plt.subplots, creating multiple plots in one figure would be messy and hard to control. You would have to manually position each plot, which is slow and error-prone. Plt.subplots solves this by automatically arranging plots in a grid, making it easy to compare data side-by-side. This is important for clear data storytelling and analysis.
Where it fits
Before learning plt.subplots, you should know how to create a single plot using matplotlib. After mastering plt.subplots, you can learn advanced layout controls, sharing axes, and customizing subplot spacing for professional-quality visualizations.
Mental Model
Core Idea
Plt.subplots creates a grid of plot areas arranged by rows and columns, giving you a clean canvas to draw multiple charts in one figure.
Think of it like...
Imagine a photo album page with slots arranged in rows and columns. Each slot holds one photo, just like each subplot holds one chart. Plt.subplots sets up the empty slots for you to fill.
Figure (canvas)
┌───────────────┐
│  Row 1       │
│ ┌─────┐ ┌─────┐ │
│ │ Ax1 │ │ Ax2 │ │
│ └─────┘ └─────┘ │
│  Row 2       │
│ ┌─────┐ ┌─────┐ │
│ │ Ax3 │ │ Ax4 │ │
│ └─────┘ └─────┘ │
└───────────────┘

Rows and columns form a grid of Axes inside the Figure.
Build-Up - 7 Steps
1
FoundationCreating a single subplot
🤔
Concept: Learn how plt.subplots creates one plot area and returns figure and axis objects.
import matplotlib.pyplot as plt fig, ax = plt.subplots() ax.plot([1, 2, 3], [4, 5, 6]) plt.show()
Result
A single line plot appears in a window.
Understanding that plt.subplots returns a figure and an axis object is key to controlling where and how your plot appears.
2
FoundationSpecifying rows and columns
🤔
Concept: You can tell plt.subplots how many rows and columns of plots you want by passing integers.
fig, axes = plt.subplots(2, 3) # 2 rows, 3 columns for ax in axes.flat: ax.plot([1, 2, 3], [1, 4, 9]) plt.show()
Result
A figure with 6 plots arranged in 2 rows and 3 columns, each showing the same line plot.
Rows and columns define the grid size, and plt.subplots creates that many axes ready for plotting.
3
IntermediateAccessing individual subplots
🤔Before reading on: Do you think axes from plt.subplots(2, 2) is a list or a 2D array? Commit to your answer.
Concept: The axes returned are a 2D array when rows and columns are more than 1, letting you access each subplot by row and column index.
fig, axes = plt.subplots(2, 2) axes[0, 0].plot([1, 2, 3], [1, 2, 3]) # top-left plot axes[1, 1].plot([1, 2, 3], [3, 2, 1]) # bottom-right plot plt.show()
Result
A figure with 4 plots arranged in 2x2 grid, with different lines in top-left and bottom-right plots.
Knowing axes is a 2D array helps you target exactly which subplot to draw on, enabling precise control.
4
IntermediateFlattening axes for easy iteration
🤔Before reading on: Would axes.flat give you a 1D iterator or a 2D array? Commit to your answer.
Concept: axes.flat turns the 2D array of axes into a flat iterator, making it easier to loop over all subplots in one go.
fig, axes = plt.subplots(2, 2) for ax in axes.flat: ax.plot([1, 2, 3], [3, 2, 1]) plt.show()
Result
All 4 subplots show the same line plot, drawn by looping over a flat iterator.
Flattening axes simplifies code when you want to apply the same plot or style to all subplots.
5
IntermediateCreating a single row or column grid
🤔
Concept: You can create just one row or one column of subplots by setting rows or columns to 1.
fig, axes = plt.subplots(1, 3) # 1 row, 3 columns for ax in axes: ax.plot([1, 2, 3], [2, 4, 6]) plt.show()
Result
A figure with 3 plots arranged horizontally in one row.
When rows or columns is 1, axes is a 1D array, so indexing changes accordingly.
6
AdvancedSharing axes between subplots
🤔Before reading on: Do you think sharing axes means all plots show the exact same scale or just linked scales? Commit to your answer.
Concept: You can share x or y axes between subplots so they use the same scale, making comparison easier.
fig, axes = plt.subplots(2, 2, sharex=True, sharey=True) axes[0, 0].plot([1, 2, 3], [1, 4, 9]) axes[1, 1].plot([1, 2, 3], [9, 4, 1]) plt.show()
Result
All subplots share the same x and y axis scales, so zooming or limits apply to all.
Sharing axes helps maintain consistent scales across plots, improving visual comparison.
7
ExpertHandling axes shape for single subplot cases
🤔Before reading on: When plt.subplots(1,1) is called, is axes an array or a single object? Commit to your answer.
Concept: When rows and columns are both 1, axes is a single Axes object, not an array, which can cause bugs if you expect an array.
fig, ax = plt.subplots(1, 1) ax.plot([1, 2, 3], [3, 2, 1]) # axes is not an array here fig, axes = plt.subplots(2, 2) print(type(axes)) # fig, ax = plt.subplots() print(type(ax)) #
Result
Single subplot returns a single Axes object; multiple subplots return an array of Axes.
Knowing this prevents bugs when writing code that handles both single and multiple subplots dynamically.
Under the Hood
Plt.subplots internally creates a Figure object as the canvas. It then creates multiple Axes objects arranged in a grid defined by rows and columns. These Axes are placed using a grid specification that manages their size and position automatically. The function returns the Figure and the array of Axes so you can draw on each subplot independently.
Why designed this way?
Matplotlib was designed to separate the figure (overall window) from axes (individual plots) for flexibility. Plt.subplots was introduced to simplify creating multiple plots without manual positioning. The grid layout system balances ease of use with control, avoiding the complexity of manual subplot placement.
Figure
┌─────────────────────────────┐
│ Grid Spec (rows x columns)  │
│ ┌─────┬─────┬─────┐         │
│ │ Ax1 │ Ax2 │ Ax3 │         │
│ ├─────┼─────┼─────┤         │
│ │ Ax4 │ Ax5 │ Ax6 │         │
│ └─────┴─────┴─────┘         │
└─────────────────────────────┘

Figure holds grid spec which manages Axes placement.
Myth Busters - 4 Common Misconceptions
Quick: Does plt.subplots always return an array of axes, even for one subplot? Commit yes or no.
Common Belief:plt.subplots always returns an array of axes, no matter how many subplots you create.
Tap to reveal reality
Reality:If you create only one subplot (rows=1, cols=1), plt.subplots returns a single Axes object, not an array.
Why it matters:Assuming axes is always an array can cause errors when indexing or looping over axes in single subplot cases.
Quick: Does setting sharex=True mean each subplot has its own x-axis scale? Commit yes or no.
Common Belief:Sharing axes means each subplot has independent scales but linked ticks.
Tap to reveal reality
Reality:Sharing axes means all subplots use the exact same scale and limits for that axis.
Why it matters:Misunderstanding this can lead to confusing plots where zooming or limits affect all subplots unexpectedly.
Quick: Does plt.subplots automatically adjust spacing between subplots? Commit yes or no.
Common Belief:plt.subplots automatically spaces subplots perfectly with no overlap or crowding.
Tap to reveal reality
Reality:By default, subplots can overlap or have tight spacing; you often need to call plt.tight_layout() or adjust spacing manually.
Why it matters:Ignoring spacing adjustments can produce unreadable plots with overlapping labels or titles.
Quick: Can you pass negative numbers for rows or columns in plt.subplots? Commit yes or no.
Common Belief:You can pass any integer values for rows and columns, including zero or negative numbers.
Tap to reveal reality
Reality:Rows and columns must be positive integers; zero or negative values cause errors.
Why it matters:Passing invalid values crashes the program, so input validation is important.
Expert Zone
1
When sharing axes, the underlying Axis objects are linked, so changing limits on one subplot affects all linked subplots immediately.
2
The shape of the axes array depends on the number of rows and columns; if either is 1, axes is a 1D array, otherwise 2D, which affects indexing.
3
Using constrained_layout=True in plt.subplots can automatically manage subplot spacing better than tight_layout, but it may have compatibility issues with some plot elements.
When NOT to use
Plt.subplots is not ideal when you need highly customized subplot layouts like irregular grids or overlapping plots. In such cases, use GridSpec or manual Axes placement for full control.
Production Patterns
In production, plt.subplots is often combined with shared axes and constrained_layout for clean dashboards. Developers write loops over axes.flat to populate plots dynamically from data sources, and handle single vs multiple subplot cases carefully to avoid bugs.
Connections
GridSpec in matplotlib
Plt.subplots uses GridSpec internally to arrange subplots in a grid.
Understanding GridSpec helps you customize subplot layouts beyond the simple rows and columns of plt.subplots.
Responsive web grid layouts (CSS Grid)
Both arrange content in rows and columns for clear organization.
Knowing how CSS Grid works helps grasp how plt.subplots arranges plots visually in a grid.
Spreadsheet cells
Subplots are like cells in a spreadsheet grid, each holding independent content.
This connection helps understand how each subplot is independent but arranged in a structured grid.
Common Pitfalls
#1Assuming axes is always an array and trying to index it when only one subplot exists.
Wrong approach:fig, axes = plt.subplots(1, 1) axes[0].plot([1, 2, 3], [4, 5, 6]) # Error: 'AxesSubplot' object is not subscriptable
Correct approach:fig, ax = plt.subplots(1, 1) ax.plot([1, 2, 3], [4, 5, 6])
Root cause:Not knowing that a single subplot returns a single Axes object, not an array.
#2Not adjusting subplot spacing, causing labels and titles to overlap.
Wrong approach:fig, axes = plt.subplots(2, 2) # plotting code plt.show() # Overlapping labels
Correct approach:fig, axes = plt.subplots(2, 2) # plotting code plt.tight_layout() plt.show()
Root cause:Ignoring the need for layout adjustment after creating multiple subplots.
#3Passing zero or negative numbers for rows or columns.
Wrong approach:fig, axes = plt.subplots(0, 3) # ValueError: Number of rows must be positive
Correct approach:fig, axes = plt.subplots(1, 3) # Valid positive number of rows
Root cause:Not validating input parameters before calling plt.subplots.
Key Takeaways
Plt.subplots creates a figure and a grid of subplots arranged by rows and columns, returning a figure and axes objects.
The axes returned can be a single object or an array depending on the number of subplots, which affects how you access them.
Sharing axes between subplots helps keep scales consistent, improving visual comparison across plots.
You often need to adjust subplot spacing manually using tight_layout or constrained_layout to avoid overlapping elements.
Understanding the internal grid layout and axes array shape prevents common bugs and enables flexible, clean multi-plot figures.

Practice

(1/5)
1. What does plt.subplots(2, 3) create in matplotlib?
easy
A. A figure with 2 rows and 3 columns of subplots
B. A figure with 3 rows and 2 columns of subplots
C. A single plot with size 2x3 inches
D. A figure with 6 rows and 1 column of subplots

Solution

  1. Step 1: Understand plt.subplots parameters

    The first parameter is the number of rows, the second is columns.
  2. Step 2: Apply to given code

    plt.subplots(2, 3) means 2 rows and 3 columns of subplots.
  3. Final Answer:

    A figure with 2 rows and 3 columns of subplots -> Option A
  4. Quick Check:

    rows=2, columns=3 = B [OK]
Hint: First number = rows, second = columns in plt.subplots [OK]
Common Mistakes:
  • Confusing rows and columns order
  • Thinking parameters set figure size
  • Assuming single plot created
2. Which of the following is the correct syntax to create a 3x1 subplot grid using plt.subplots?
easy
A. fig, axes = plt.subplots(1, 3)
B. fig, axes = plt.subplots(3)
C. fig, axes = plt.subplots(3, 1)
D. fig, axes = plt.subplots(rows=3, cols=1)

Solution

  1. Step 1: Recall plt.subplots parameter order

    The first argument is rows, second is columns.
  2. Step 2: Match to 3 rows and 1 column

    plt.subplots(3, 1) creates 3 rows and 1 column.
  3. Final Answer:

    fig, axes = plt.subplots(3, 1) -> Option C
  4. Quick Check:

    3 rows, 1 column = C [OK]
Hint: Remember: plt.subplots(rows, columns) order matters [OK]
Common Mistakes:
  • Swapping rows and columns
  • Using single number for both dimensions
  • Using keyword arguments incorrectly
3. What is the shape of axes returned by fig, axes = plt.subplots(2, 2)?
medium
A. A 1D array with 4 axes objects
B. A 2D array with shape (2, 2) of axes objects
C. A list of 2 axes objects
D. A single axes object

Solution

  1. Step 1: Understand axes shape for multiple rows and columns

    When rows and columns are more than 1, axes is a 2D array matching shape.
  2. Step 2: Apply to plt.subplots(2, 2)

    axes will be a 2x2 array of axes objects.
  3. Final Answer:

    A 2D array with shape (2, 2) of axes objects -> Option B
  4. Quick Check:

    Multiple rows and columns = 2D axes array [OK]
Hint: Multiple rows & columns -> axes is 2D array [OK]
Common Mistakes:
  • Assuming axes is always 1D
  • Confusing number of axes with shape
  • Expecting a single axes object
4. Given the code:
fig, axes = plt.subplots(2, 2)
axes[2, 0].plot([1, 2, 3])

What error will occur?
medium
A. No error, plot will display
B. TypeError: axes object is not subscriptable
C. AttributeError: 'AxesSubplot' object has no attribute 'plot'
D. IndexError: index 2 is out of bounds for axis 0 with size 2

Solution

  1. Step 1: Check axes shape from plt.subplots(2, 2)

    axes is a 2x2 array with indices 0 and 1 for rows and columns.
  2. Step 2: Analyze axes[2, 0] access

    Index 2 for rows is out of bounds since max index is 1.
  3. Final Answer:

    IndexError: index 2 is out of bounds for axis 0 with size 2 -> Option D
  4. Quick Check:

    axes shape (2,2), index 2 invalid [OK]
Hint: Check axes array shape before indexing [OK]
Common Mistakes:
  • Using invalid indices beyond shape
  • Confusing axes as list instead of array
  • Expecting no error on wrong index
5. You want to create a 2x3 grid of subplots and plot a line on each subplot with data from a list of 6 arrays. Which code correctly accesses each subplot to plot inside a nested loop?
hard
A. for i in range(2): for j in range(3): axes[i][j].plot(data[i*3 + j])
B. for i in range(2): for j in range(3): axes[i, j].plot(data[i + j])
C. for i in range(3): for j in range(2): axes[i][j].plot(data[i*2 + j])
D. for i in range(2): for j in range(3): axes[j][i].plot(data[i*3 + j])

Solution

  1. Step 1: Understand axes shape and indexing

    plt.subplots(2, 3) creates axes as a 2x3 array, indexed as axes[row][col].
  2. Step 2: Correctly map data list to subplot indices

    Data index = row * number_of_columns + column = i*3 + j matches subplot position.
  3. Final Answer:

    for i in range(2): for j in range(3): axes[i][j].plot(data[i*3 + j]) -> Option A
  4. Quick Check:

    axes[row][col], data index = row*cols + col [OK]
Hint: Use axes[row][col] and data index = row*cols + col [OK]
Common Mistakes:
  • Swapping row and column loops
  • Incorrect data indexing
  • Using axes[j][i] instead of axes[i][j]
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard