When I first started using Matplotlib in Python more than a decade ago, one of the challenges I faced was how to visualize two datasets with different scales on the same chart. For example, I often had to compare U.S. sales revenue and customer satisfaction scores, both important metrics but measured in completely different units.
At first glance, it seemed impossible to plot them clearly without confusing the audience. But that’s when I discovered the power of two Y axes in Matplotlib. This feature allows you to display two variables side-by-side, each with its own scale, yet sharing the same X-axis.
In this tutorial, I’ll walk you through two practical Python methods to create dual Y-axis charts, one for the same scale and another for different scales.
Plot Two Y Axes with the Same Scale in Python
Sometimes, you may want to plot two datasets that share the same unit or range, for example, comparing monthly sales revenue from two states in the U.S., such as California and Texas. In such cases, having two Y axes with the same scale can make comparisons clearer without distorting the visual message.
Below are two methods to create dual Y axes with the same scale in Matplotlib.
Method 1 – Use twinx() for Same Scale
The simplest and most common way to add a second Y axis in Matplotlib Python is by using the twinx() function. This method creates a duplicate of the original Y axis, sharing the same X-axis but allowing separate data series to be plotted.
Here’s how you can do it step-by-step:
import matplotlib.pyplot as plt
import numpy as np
# Sample data
months = np.arange(1, 13)
sales_california = np.random.randint(200, 500, size=12)
sales_texas = np.random.randint(180, 460, size=12)
# Create the figure and first axis
fig, ax1 = plt.subplots(figsize=(10, 6))
# Plot California sales
ax1.plot(months, sales_california, color='blue', marker='o', label='California Sales')
ax1.set_xlabel('Month')
ax1.set_ylabel('Sales (in $1000s)', color='blue')
ax1.tick_params(axis='y', labelcolor='blue')
# Create a second Y-axis sharing the same X-axis
ax2 = ax1.twinx()
# Plot Texas sales
ax2.plot(months, sales_texas, color='green', marker='s', linestyle='--', label='Texas Sales')
ax2.set_ylabel('Sales (in $1000s)', color='green')
ax2.tick_params(axis='y', labelcolor='green')
# Add title and legend
plt.title('Monthly Sales Comparison: California vs Texas')
fig.tight_layout()
plt.show()You can refer to the screenshot below to see the output.

This Python example creates two Y axes that share the same scale, making it easy to compare the sales trends visually.
If both datasets use similar units (like dollars or percentages), this method keeps your visualization simple and effective.
Method 2 – Use Subplots with Shared Y-Axis
Another approach I often use is creating two subplots that share the same Y-axis. This gives you more control over spacing and layout while maintaining visual clarity.
Here’s how you can do it:
import matplotlib.pyplot as plt
import numpy as np
# Data
months = np.arange(1, 13)
sales_california = np.random.randint(250, 500, size=12)
sales_texas = np.random.randint(200, 480, size=12)
# Create subplots with shared Y-axis
fig, (ax1, ax2) = plt.subplots(1, 2, sharey=True, figsize=(12, 6))
# Plot California sales
ax1.plot(months, sales_california, color='orange', marker='o')
ax1.set_title('California Sales')
ax1.set_xlabel('Month')
ax1.set_ylabel('Sales (in $1000s)')
# Plot Texas sales
ax2.plot(months, sales_texas, color='purple', marker='s')
ax2.set_title('Texas Sales')
ax2.set_xlabel('Month')
# Add main title
plt.suptitle('Monthly Sales Comparison (Same Scale)')
plt.tight_layout()
plt.show()You can refer to the screenshot below to see the output.

This approach is great when you want to visually separate the two datasets but still maintain the same Y-axis scale for accurate comparison.
I often use this method when presenting reports to clients who prefer side-by-side visualizations.
Plot Two Y Axes with Different Scales in Python
Now let’s move on to a more common scenario, when your datasets have different scales or units. For instance, you might want to compare U.S. monthly sales revenue (in dollars) and customer satisfaction scores (on a scale of 1–10).
If you plot them on the same scale, one dataset will dominate the chart, making the other nearly invisible. This is where dual Y axes with different scales come to the rescue.
Method 1 – Use twinx() for Different Scales
Yes, the same twinx() function can handle different scales easily. You just need to adjust the Y-axis limits or let Matplotlib automatically handle the scaling.
Here’s a complete Python example:
import matplotlib.pyplot as plt
import numpy as np
# Data
months = np.arange(1, 13)
revenue = np.random.randint(50000, 120000, size=12)
satisfaction = np.random.uniform(6.5, 9.5, size=12)
# Create figure and axis
fig, ax1 = plt.subplots(figsize=(10, 6))
# Plot revenue on primary Y-axis
ax1.bar(months, revenue, color='skyblue', label='Revenue ($)')
ax1.set_xlabel('Month')
ax1.set_ylabel('Revenue ($)', color='blue')
ax1.tick_params(axis='y', labelcolor='blue')
# Create secondary Y-axis for satisfaction
ax2 = ax1.twinx()
ax2.plot(months, satisfaction, color='red', marker='o', label='Customer Satisfaction')
ax2.set_ylabel('Satisfaction Score', color='red')
ax2.tick_params(axis='y', labelcolor='red')
# Add title and legend
plt.title('Monthly Revenue vs Customer Satisfaction (Different Scales)')
fig.tight_layout()
plt.show()You can refer to the screenshot below to see the output.

This visualization clearly shows how customer satisfaction trends relate to revenue performance, even though they are measured on completely different scales. It’s one of my favorite Python techniques for business analytics dashboards.
Method 2 – Use secondary_yaxis() in Matplotlib
Starting from Matplotlib 3.1, you can use the secondary_yaxis() method to create a second Y-axis that applies a mathematical transformation to the first one. This is useful when the two datasets are related but not directly comparable in scale.
Here’s an example where we visualize temperature in Fahrenheit and Celsius using a conversion function.
import matplotlib.pyplot as plt
import numpy as np
# Data
days = np.arange(1, 11)
temperature_f = np.random.randint(60, 100, size=10)
# Conversion functions
def fahrenheit_to_celsius(f):
return (f - 32) * 5/9
def celsius_to_fahrenheit(c):
return c * 9/5 + 32
# Create plot
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(days, temperature_f, color='darkorange', marker='o')
ax.set_xlabel('Day')
ax.set_ylabel('Temperature (°F)', color='darkorange')
ax.tick_params(axis='y', labelcolor='darkorange')
# Add secondary Y-axis for Celsius
ax2 = ax.secondary_yaxis('right', functions=(fahrenheit_to_celsius, celsius_to_fahrenheit))
ax2.set_ylabel('Temperature (°C)', color='teal')
ax2.tick_params(axis='y', labelcolor='teal')
plt.title('Daily Temperature in Fahrenheit and Celsius')
plt.tight_layout()
plt.show()You can refer to the screenshot below to see the output.

This method is extremely useful for scientific or engineering applications where you need to show two related units together.
I’ve used this approach in weather analytics dashboards for clients who wanted both Fahrenheit and Celsius displayed simultaneously.
Best Practices for Using Two Y Axes in Python
Over the years, I’ve learned that while dual Y axes can be powerful, they can also be misleading if not used carefully. Here are a few best practices I recommend:
- Use contrasting colors for each axis and dataset.
- Label both Y axes clearly to avoid confusion.
- Avoid using two Y axes for unrelated metrics (e.g., revenue vs. website traffic).
- Add gridlines or annotations to guide the reader’s eye.
- Keep your chart simple and focused — clarity always wins.
When you’re working with Matplotlib in Python, mastering dual Y axes opens up new possibilities for storytelling with data. Whether you’re comparing two similar datasets or exploring relationships between variables with different scales, these techniques will help you communicate insights more effectively.
You may also like to read:
- Invert the Y-Axis in Matplotlib imshow
- Create Two Y Axes Bar Plot in Matplotlib
- Invert the Y-Axis in 3D Plot using Matplotlib
- Invert Secondary Y-Axis in Matplotlib using Python

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.