When I first started creating complex dashboards in Python, I often struggled with mismatched scales. I would plot several charts side-by-side, only to realize that one x-axis went to 100 while the other stopped at 50.
This makes it incredibly difficult for your audience to compare trends across different datasets.
In this tutorial, I will show you exactly how I set uniform axis limits for all subplots in Matplotlib using a few different professional techniques.
Unify Axis Limits
If you are analyzing retail sales across different US states, having different scales can be misleading.
For instance, a spike in California might look smaller than a spike in Wyoming just because the y-axis auto-scaled differently.
By setting the same limits for every subplot, you ensure a “fair” visual comparison across your entire figure.
Method 1: Use the sharex and sharey Parameters
This is my go-to method when I know from the start that all my plots should share the same scale.
When you use plt.subplots(), you can pass the sharex or sharey arguments. This tells Matplotlib to link the axes automatically.
Here is an example where I compare the monthly housing price index for three major US cities.
import matplotlib.pyplot as plt
import numpy as np
# Sample Data: Monthly Price Index (Simulated)
months = np.arange(1, 13)
ny_prices = [105, 107, 110, 112, 115, 118, 120, 122, 125, 128, 130, 135]
tx_prices = [95, 96, 98, 100, 102, 105, 108, 110, 112, 115, 118, 120]
ca_prices = [120, 122, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170]
# Creating the subplots with shared Y axis
fig, axes = plt.subplots(1, 3, figsize=(15, 5), sharey=True)
# Plotting NYC data
axes[0].plot(months, ny_prices, color='blue', marker='o')
axes[0].set_title('New York Real Estate')
axes[0].set_xlabel('Month')
axes[0].set_ylabel('Price Index')
# Plotting Texas data
axes[1].plot(months, tx_prices, color='red', marker='s')
axes[1].set_title('Texas Real Estate')
axes[1].set_xlabel('Month')
# Plotting California data
axes[2].plot(months, ca_prices, color='green', marker='^')
axes[2].set_title('California Real Estate')
axes[2].set_xlabel('Month')
plt.tight_layout()
plt.show()You can refer to the screenshot below to see the output.

By setting sharey=True, Matplotlib automatically finds the maximum and minimum values across all datasets and applies them to every subplot.
I find this particularly useful because it also hides the inner tick labels, making the chart look much cleaner.
Method 2: Manually Iterating Through Axes Using a Loop
Sometimes, I don’t want to “link” the axes, but I still want them to have a specific range that I define manually.
In this scenario, I prefer to use a simple for loop to apply the set_ylim or set_xlim functions to every subplot object.
Imagine we are looking at the percentage of EV (Electric Vehicle) adoption across different US regions.
import matplotlib.pyplot as plt
# Regions and their EV adoption percentages
regions = ['Northeast', 'Midwest', 'South', 'West']
ev_adoption = [12, 8, 6, 25]
# Create a 2x2 grid
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
# Data for individual states in those regions (Example values)
data = {
(0,0): ("New York", 15),
(0,1): ("Illinois", 10),
(1,0): ("Florida", 7),
(1,1): ("California", 28)
}
# Plotting and setting limits manually via a loop
for (row, col), (state, value) in data.items():
ax = axes[row, col]
ax.bar(state, value, color='teal')
ax.set_title(f'Market Share: {state}')
# Setting the same Y-limit for all subplots (0 to 35%)
ax.set_ylim(0, 35)
plt.subplots_adjust(hspace=0.4)
plt.show()You can refer to the screenshot below to see the output.

In this case, I explicitly set ax.set_ylim(0, 35). I use this method when I want the white space at the top of my charts to be consistent, regardless of the data.
Method 3: Use the setp() Function
If you have already created your plots and don’t want to write a loop, you can use the plt.setp() function.
The setp (set property) function is a hidden gem in Matplotlib that allows you to change properties for a list of objects at once.
I often use this when I am working with a large grid of subplots and want a quick one-liner to fix the scales.
import matplotlib.pyplot as plt
import numpy as np
# Generating random data for US Stock tickers
x = np.linspace(0, 10, 100)
tickers = ['AAPL', 'MSFT', 'GOOGL', 'AMZN']
fig, axes = plt.subplots(2, 2, figsize=(10, 7))
flat_axes = axes.flatten()
for i, ax in enumerate(flat_axes):
ax.plot(x, np.sin(x + i) + np.random.normal(0, 0.1, 100))
ax.set_title(tickers[i])
# Using setp to set all y-axis limits at once
plt.setp(axes, ylim=(-2, 2), xlim=(0, 10))
plt.tight_layout()
plt.show()You can refer to the screenshot below to see the output.

The beauty of plt.setp(axes, …) is that it handles the flattening of the axes array for you. It is a very efficient way to clean up your code.
Method 4: Dynamically Setting Limits Based on Data
There are times when I don’t know the limits beforehand. I want the limits to be based on the “global” maximum of all subplots.
To do this, I first calculate the overall min and max from all my data arrays and then apply them.
This ensures that the “biggest” data point in the entire project still fits comfortably within every subplot.
import matplotlib.pyplot as plt
# GDP Growth percentages for different years
data_2021 = [5.7, 6.1, 4.9]
data_2022 = [2.1, 1.9, 2.6]
data_2023 = [3.0, 4.5, 3.2]
# Combine all data to find global limits
all_values = data_2021 + data_2022 + data_2023
global_min = min(all_values) - 1
global_max = max(all_values) + 1
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(12, 4))
ax1.plot(data_2021, marker='o')
ax1.set_title('2021 Growth')
ax2.plot(data_2022, marker='o')
ax2.set_title('2022 Growth')
ax3.plot(data_2023, marker='o')
ax3.set_title('2023 Growth')
# Apply global limits
for ax in [ax1, ax2, ax3]:
ax.set_ylim(global_min, global_max)
plt.show()This approach is highly robust and is what I recommend for production-level automated reporting.
Things to Keep in Mind
When you set shared axis limits, you might find that your labels overlap or look crowded.
I always recommend using plt.tight_layout() or fig.subplots_adjust() to give your charts some breathing room.
Also, remember that if you use sharex=True, changing the limit on one subplot will automatically update the limits on all other linked subplots.
In this tutorial, I have shown you several ways to set axis limits for all subplots in Matplotlib.
Whether you use the built-in sharey parameter or a custom loop, keeping your scales consistent is a hallmark of professional data visualization.
You may also like to read:
- Create a Matplotlib Boxplot for Time Series Data in Python
- Plot Multiple Bar Charts with Time Series in Matplotlib
- Matplotlib 2D Color Surface Plots
- How to Set Axis Limits in Matplotlib 3D Plots

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.