Chapter 2 – Understanding Figures, Axes, and Subplots in Matplotlib
In the previous chapter, you learned how to create your first simple line graph using matplotlib.pyplot. In this chapter, we’ll go a level deeper and explore how Matplotlib actually organizes a figure internally. You’ll understand what a Figure is, what Axes are, how they differ, and how you can use Subplots to display multiple charts in the same window.
✅ Why Understanding Figures and Axes Matters
Beginners often think Matplotlib plots are just one command like plt.plot(). But behind the scenes, every chart is part of a complex yet elegant hierarchy. Understanding that structure gives you full control over positioning, scaling, and styling — essential for professional, customized visualizations.
Think of Matplotlib like a painting:
- The Figure is the canvas — the overall window or page.
- The Axes are the individual drawing areas where your data lives.
- Each Axes has its own X and Y axes, title, labels, and ticks.
When you call plt.plot(), Matplotlib quietly creates both a Figure and an Axes for you. But when you need multiple plots in one figure, or want fine-grained control, you must create them explicitly.
✅ The Figure Object
A Figure in Matplotlib is the overall container that can hold one or more Axes. It’s where everything — titles, legends, images, and charts — is drawn. Think of it as the sheet of paper on which you’ll paint multiple graphs.
import matplotlib.pyplot as plt
fig = plt.figure()
print(type(fig))
This prints <class 'matplotlib.figure.Figure'>. Now you have a blank canvas. However, if you don’t add any Axes, nothing will be visible when you call plt.show().
You can specify figure size (in inches) and resolution (DPI) when creating it:
fig = plt.figure(figsize=(8,6), dpi=100)
This makes your canvas 8 inches wide, 6 inches tall, with 100 dots per inch — perfect for most screens or reports.
✅ The Axes Object
Now, let’s add the actual area where data is drawn. Each Axes object represents a single plot region with its own coordinate system. You can add one like this:
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
ax.plot([1,2,3,4], [10,20,25,30])
plt.show()
The four numbers inside the list define the position of the Axes within the figure: [left, bottom, width, height], where each value ranges from 0 to 1 (relative to the figure size).
- left = distance from left edge of figure
- bottom = distance from bottom edge
- width = width of the axes area
- height = height of the axes area
That’s how you can precisely place charts inside one figure — useful when designing dashboards or multi-panel reports.
✅ The Object-Oriented Interface
In Chapter 1, we used the simpler state-based interface (plt.plot()). Now we’ll move to the object-oriented interface, which gives much better control.
fig, ax = plt.subplots()
ax.plot([1,2,3,4], [10,20,25,30])
ax.set_title('Simple Line Chart')
ax.set_xlabel('X-Axis')
ax.set_ylabel('Y-Axis')
plt.show()
Here, plt.subplots() automatically creates both a Figure and a single Axes object. You can access methods like set_title(), set_xlabel(), and set_ylabel() directly from the ax object.
This is considered the best practice in Matplotlib because it scales naturally when you add more subplots later.
✅ Adding Multiple Axes (Manual Method)
You can manually add several Axes inside one Figure using add_axes() multiple times:
fig = plt.figure()
ax1 = fig.add_axes([0.1, 0.1, 0.8, 0.8])
ax2 = fig.add_axes([0.2, 0.5, 0.4, 0.3])
ax1.plot([1,2,3], [1,2,3])
ax2.plot([1,2,3], [1,4,9])
plt.show()
Here, the second Axes (ax2) is drawn on top of the first one — like a mini chart within a chart. This layout is perfect for showing zoomed-in views or highlighting specific trends.
✅ Using Subplots for Grids of Charts
Manually positioning Axes can get messy. That’s why Matplotlib provides a simpler system — plt.subplots() — for grid layouts. For example:
fig, axes = plt.subplots(2, 2)
axes[0,0].plot([1,2,3], [1,2,3])
axes[0,1].plot([1,2,3], [1,4,9])
axes[1,0].plot([1,2,3], [1,8,27])
axes[1,1].plot([1,2,3], [1,16,81])
plt.show()
This creates a 2×2 grid of charts inside a single Figure. Each element of the axes array corresponds to one subplot. You can access and modify each independently.
By default, subplots() arranges them neatly with automatic spacing. You can also set figsize for the overall layout.
✅ Adjusting Spacing Between Subplots
If your titles or labels overlap, you can use plt.tight_layout() to automatically adjust the spacing:
fig, axes = plt.subplots(2, 2)
...
plt.tight_layout()
plt.show()
Alternatively, use fig.subplots_adjust() for manual control over margins.
✅ Sharing Axes Between Subplots
When creating multiple plots with the same scale, it’s convenient to share their X or Y axes:
fig, axes = plt.subplots(2, 1, sharex=True)
axes[0].plot([1,2,3], [2,4,8])
axes[1].plot([1,2,3], [1,3,9])
plt.show()
Now, both plots share the same X-axis range, making comparison straightforward. This is especially useful in time-series data where multiple indicators align on the same timeline.
✅ Adding Titles to Each Subplot
You can give each subplot its own title using set_title() and a main figure-level title with fig.suptitle():
fig, axes = plt.subplots(2, 2)
axes[0,0].set_title('Linear')
axes[0,1].set_title('Quadratic')
axes[1,0].set_title('Cubic')
axes[1,1].set_title('Quartic')
fig.suptitle('Multiple Functions Plot')
plt.tight_layout()
plt.show()
The main title gives viewers quick context, while each subplot title specifies what’s being shown.
✅ Color and Style Customization in Subplots
Each Axes can have its own style. You can differentiate datasets using color, markers, or line style:
axes[0,0].plot(x, y, color='red', linestyle='--')
axes[0,1].plot(x, y, color='green', marker='o')
axes[1,0].plot(x, y, color='blue', linewidth=3)
axes[1,1].plot(x, y, color='purple', linestyle='-.')
These subtle visual cues help distinguish multiple functions or categories in one figure.
✅ Understanding the Axes Limits
By default, Matplotlib automatically scales your axes based on the data. However, you can manually control the limits using set_xlim() and set_ylim():
ax.set_xlim(0, 10)
ax.set_ylim(0, 50)
This is useful when you need consistency between different plots or to zoom into a specific region.
✅ Legends and Labels Across Subplots
Each subplot can have its own legend, or you can place a single global legend for all. Here’s an example:
fig, axes = plt.subplots(1, 2)
axes[0].plot(x, y, label='Product A')
axes[1].plot(x, [val*2 for val in y], label='Product B')
axes[0].legend()
axes[1].legend()
plt.show()
Legends automatically identify which line corresponds to which dataset. For multi-chart dashboards, this keeps visual storytelling clear.
✅ Saving Figures to File
Matplotlib allows you to save figures directly in formats like PNG, JPG, PDF, or SVG. You can specify the resolution (DPI) and transparent background too:
fig.savefig('multiple_plots.png', dpi=300, bbox_inches='tight')
The bbox_inches='tight' argument ensures that all elements, including labels and titles, fit nicely inside the saved image without cropping.
✅ Combining Everything Together
Let’s combine what we’ve learned into a single, clean example.
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
fig, axes = plt.subplots(2, 2, figsize=(10,8))
axes[0,0].plot(x, np.sin(x))
axes[0,1].plot(x, np.cos(x))
axes[1,0].plot(x, np.tan(x))
axes[1,1].plot(x, np.exp(-x))
axes[0,0].set_title('Sine')
axes[0,1].set_title('Cosine')
axes[1,0].set_title('Tangent')
axes[1,1].set_title('Exponential Decay')
fig.suptitle('Trigonometric and Exponential Functions', fontsize=16)
plt.tight_layout()
plt.show()
This creates a 2×2 dashboard showcasing four different mathematical functions on a single canvas. You’ve just built a professional-style layout using only a few lines of Matplotlib code.
✅ Best Practices for Using Figures and Subplots
- Always use the object-oriented syntax (
fig, ax = plt.subplots()) for cleaner code. - Set
figsizeearly to ensure clarity and uniformity. - Use
tight_layout()orconstrained_layout=Trueto avoid overlapping text. - Keep color schemes consistent when comparing related data.
- Use
suptitlefor figure-level context. - Save figures at high DPI for presentations or publications.
✅ Summary of Chapter 2
In this chapter, you’ve mastered the inner structure of Matplotlib. You now know that:
- A Figure is the top-level container — the canvas of your visualization.
- An Axes is where the actual plot resides, complete with its coordinate system.
- Subplots make it easy to create multiple Axes in one figure.
- You can control spacing, share axes, and customize styles for professional-grade layouts.
With this knowledge, you’re ready for the next step — learning about plot types, including bar charts, scatter plots, and histograms, which we’ll explore in Chapter 3: Plot Types and Data Representation in Matplotlib.
