Lesson 11 · Data visualisation in python
Mastering Subplots and Multiple Axes in Matplotlib for Effective Data Visualization
Welcome! Today we will learn how to create multiple plots in a single figure using Python's Matplotlib. We will explore how to show separate charts side by…
- CourseData visualisation in python
- Lesson11 of 34
- Video14 min
- FormatJupyter notebook · 13 code cells
What you'll learn
Data
No separate download needed — the notebook creates or downloads everything it uses.
📓 Full notebook
Download .ipynbIntroduction to Subplots and Multiple Axes in Matplotlib#
Welcome! Today we will learn how to create multiple plots in a single figure using Python's Matplotlib.
We will explore how to show separate charts side by side, and how to compare different datasets clearly.
By the end, you will know how to make more useful, professional-looking charts for your data.
Let us get started!
import warnings; warnings.filterwarnings("ignore")
# Import standard plotting libraries
import matplotlib.pyplot as plt
# Set up for nicer looking plots (optional)
plt.style.use('seaborn-v0_8-colorblind')
Why Subplots Matter#
Subplots let us compare trends, spot differences, and show more information without crowding one chart.
Imagine showing sales vs. temperature for two stores in one imagethat is what subplots help us do.
# Data setup
import pandas as pd
url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-min-temperatures.csv"
df = pd.read_csv(url)
print("Shape:", df.shape)
print(df.head())
# Simple line plot of the whole dataset
plt.figure(figsize=(8,4))
plt.plot(df['Temp'])
plt.title("Daily minimum temperatures (Melbourne, 1981-1990)")
plt.xlabel("Day")
plt.ylabel("Temperature (Celsius)")
plt.tight_layout()
plt.show()
First Steps with Subplots#
Matplotlib's subplots function is the key tool. It lets us set up a grid of plots, like laying out comic book frames.
Each 'cell' in the grid is its own area to show a chart or data.
# Your first subplot: two charts side by side
fig, axes = plt.subplots(1,2, figsize=(10,4))
axes[0].plot(df['Temp'])
axes[0].set_title("All data")
axes[1].plot(df['Temp'].head(365))
axes[1].set_title("First Year Only")
plt.tight_layout()
plt.show()
# Plotting different groups in each subplot
summer = df[df['Date'].str.contains('-12-|-01-|-02-')]
winter = df[df['Date'].str.contains('-06-|-07-|-08-')]
fig, axes = plt.subplots(1, 2, figsize=(10,4))
axes[0].plot(summer['Temp'], color='red')
axes[0].set_title("Summer Days")
axes[1].plot(winter['Temp'], color='blue')
axes[1].set_title("Winter Days")
plt.tight_layout()
plt.show()
Customizing Each Subplot#
Each subplot can have its own labels, colors, and even types of plots.
This makes it easy to compare things like lines, bars, and scatter plots at the same time.
# Different plot types in subplots
fig, axes = plt.subplots(1, 2, figsize=(12,4))
axes[0].hist(df['Temp'], bins=30, color='orange', edgecolor='black')
axes[0].set_title('Histogram of Temperatures')
axes[1].boxplot(df['Temp'])
axes[1].set_title('Boxplot of Temperatures')
axes[1].set_xticks([1])
axes[1].set_xticklabels(['Temp'])
plt.tight_layout()
plt.show()
# Subplots grid: 2x2 layout
fig, axes = plt.subplots(2, 2, figsize=(10,8))
axes[0,0].plot(df['Temp'][:100], color='purple')
axes[0,0].set_title('First 100 days')
axes[0,1].hist(df['Temp'], color='green')
axes[0,1].set_title('Histogram')
axes[1,0].boxplot(df['Temp'])
axes[1,0].set_title('Boxplot')
axes[1,1].plot(df['Temp'][-365:], color='navy')
axes[1,1].set_title('Last Year')
plt.tight_layout()
plt.show()
Sharing Axes: What and Why?#
Sometimes, we want our subplots to line up exactlyfor example, to make it easy to compare values.
Matplotlib can automatically share axes, which keeps the scales equal.
# Subplots with shared y-axis
fig, axes = plt.subplots(2, 1, sharey=True, figsize=(8,6))
axes[0].plot(df['Temp'][:365], label='Year 1')
axes[0].set_title('First Year')
axes[0].legend()
axes[1].plot(df['Temp'][-365:], label='Last Year', color='red')
axes[1].set_title('Last Year')
axes[1].legend()
plt.tight_layout()
plt.show()
# Subplots with shared x-axis
fig, axes = plt.subplots(1, 2, sharex=True, figsize=(10,4))
axes[0].plot(df['Temp'][:700])
axes[0].set_title('First 700 Days')
axes[1].plot(df['Temp'][-700:], color='teal')
axes[1].set_title('Last 700 Days')
plt.tight_layout()
plt.show()
Multiple Y-Axes (Twin Axes)#
Sometimes, we want to show two lines with very different scales on the same plot.
We can use 'twinx()' to make a second y-axis on the right.
# Twin axes: temperature and moving average
fig, ax1 = plt.subplots(figsize=(8,4))
ax1.plot(df['Temp'], color='blue', label='Temp (C)')
ax1.set_ylabel('Temperature (C)', color='blue')
ax2 = ax1.twinx()
moving_avg = df['Temp'].rolling(30).mean()
ax2.plot(moving_avg, color='orange', label='30-day avg')
ax2.set_ylabel('30-day Avg', color='orange')
plt.title('Temperature and 30-Day Average')
fig.tight_layout()
plt.show()
# Subplots combining grid and twin axes
fig, axes = plt.subplots(1,2,figsize=(12,4))
axes[0].plot(df['Temp'], color='gray')
axes[0].set_title('All Temps')
ax2b = axes[1].twinx()
axes[1].plot(df['Temp'], color='firebrick', label='Temp')
moving = df['Temp'].rolling(90).mean()
ax2b.plot(moving, color='forestgreen', label='90-day avg')
axes[1].set_title('Temp + 90-day Avg')
axes[1].legend(loc='upper left')
ax2b.legend(loc='upper right')
fig.tight_layout()
plt.show()
# Interactive: Make your own 2x1 subplot grid
print("What would you like to plot on the top subplot? Type 'line' or 'hist'.")
kind = input()
fig, axes = plt.subplots(2,1,figsize=(8,6))
if kind == 'line':
axes[0].plot(df['Temp'])
axes[0].set_title('Line plot of Temp')
else:
axes[0].hist(df['Temp'], bins=30)
axes[0].set_title('Histogram of Temp')
axes[1].boxplot(df['Temp'])
axes[1].set_title('Boxplot')
plt.tight_layout()
plt.show()
# Challenge: Make a 2x2 grid mixing plots and try custom colors
fig, axes = plt.subplots(2,2,figsize=(12,8))
axes[0,0].plot(df['Temp'], color='orchid')
axes[0,0].set_title('Temp Line')
axes[0,1].hist(df['Temp'], color='gold', edgecolor='black')
axes[0,1].set_title('Temp Histogram')
axes[1,0].boxplot(df['Temp'], patch_artist=True, boxprops=dict(facecolor='lightblue'))
axes[1,0].set_title('Temp Box')
axes[1,1].scatter(range(len(df)), df['Temp'], color='lime', alpha=0.3)
axes[1,1].set_title('Temp Scatter')
plt.tight_layout()
plt.show()
Recap: What We Learned#
You learned how to:
- Set up subplots and grids using Matplotlib
- Compare groups or trends with separate plots
- Share axes for easier comparison
- Use twin axes for different scales
- Customize plots with colors and styles
You are now ready to impress with your multi-plot figures!
Thanks for Learning with Us!#
Try playing with new datasets and different layouts.
Practice makes your skills grow.
Want more? Subscribe and explore our Python playlist on YouTube!
See you in the next lesson.
Found this useful?
All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.



