iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
To plot two independent measurements against the same x-axis in Matplotlib, create a second Axes with ax2 = ax1.twinx(). Plot one series on each Axes; the first y-axis appears on the left and the second on the right.
Plot independent data on two y-axes
Use twinx() when each series has its own y-values and scale. The second Axes shares the x-axis with the first but has an independent y-axis. This is appropriate, for example, for comparing temperature and rainfall over the same dates.
import matplotlib.pyplot as plt
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.plot(x, y_left, color="tab:red")
ax1.set_ylabel("Left quantity (unit)", color="tab:red")
ax1.tick_params(axis="y", labelcolor="tab:red")
ax2.plot(x, y_right, color="tab:blue")
ax2.set_ylabel("Right quantity (unit)", color="tab:blue")
ax2.tick_params(axis="y", labelcolor="tab:blue")
fig.tight_layout()
plt.show()
Replace x, y_left, and y_right with your data. Give each axis a label that identifies the measurement and its unit. Color-matching the axis labels and tick labels to their lines helps readers see which scale belongs to which series. tight_layout() helps prevent the right-side label from being clipped. See Matplotlib’s two-scales example and Axes.twinx documentation.
Free tools Windows power users keep installed
One-click scans. No signup required.
Show one legend for both lines
Because the lines belong to different Axes, collect their handles and labels before creating a shared legend:
#1 Best Overall
handles1, labels1 = ax1.get_legend_handles_labels()
handles2, labels2 = ax2.get_legend_handles_labels()
ax1.legend(handles1 + handles2, labels1 + labels2, loc="best")
Pass a label when plotting each line, such as ax1.plot(x, y_left, label="Left series"), so it appears in the legend.
Use a secondary axis for converted units
If the second scale is only a conversion of the same quantity—not a separate dataset—use secondary_yaxis(). For example, Celsius and Fahrenheit are two scales for temperature. Plot the data on the parent Axes; the secondary axis displays converted tick values and derives its limits from the parent.
Rank #2
def celsius_to_fahrenheit(c):
return c * 9 / 5 + 32
def fahrenheit_to_celsius(f):
return (f - 32) * 5 / 9
ax = plt.subplots()[1]
ax.plot(x, temperature_c)
ax.set_ylabel("Temperature (°C)")
secax = ax.secondary_yaxis(
"right",
functions=(celsius_to_fahrenheit, fahrenheit_to_celsius)
)
secax.set_ylabel("Temperature (°F)")
The conversion functions must accept NumPy arrays. This API is for a related scale, not for plotting an independent second series. See Matplotlib’s secondary-axis example.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Understand the scale and tick behavior
With twinx(), the y-scales are independent: Matplotlib does not synchronize their values or tick marks. That independence can be useful when measurements have very different ranges, but it can also make unrelated trends look visually aligned. Use clear labels, units, and colors, and consider separate panels if a shared chart could suggest a relationship the data does not establish.
If you specifically need the two sets of tick marks to align, Matplotlib’s twinx documentation points to LinearLocator. Aligning positions does not make the scales equivalent.
Account for the overlaid Axes in interactive plots
twinx() overlays the second Axes on the first. In interactive use, Matplotlib documents that pick events are called only for artists in the top-most Axes. If picking plotted elements matters, account for which Axes is on top; see the Axes.twinx documentation.
Quick Recap
Best Value
Rank #4
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

