matplotlib
data visualization
secondary y-axis
y-axis label
python plotting

Adding a y-axis label to secondary y-axis in matplotlib

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Matplotlib makes it easy to place two datasets with different scales on the same figure by creating a second y-axis. The key detail is that the secondary axis is a separate Axes object, so its label must be set on that object, not on the original one. Once you treat each axis independently, the labeling and styling become straightforward.

Creating a secondary y-axis with twinx

The usual pattern is to create a primary axis with plt.subplots(), then call ax.twinx() to build a second axis that shares the x-axis.

python
1import matplotlib.pyplot as plt
2
3months = ["Jan", "Feb", "Mar", "Apr", "May"]
4revenue = [12, 15, 14, 18, 21]
5conversion_rate = [1.5, 1.8, 1.7, 2.1, 2.4]
6
7fig, ax1 = plt.subplots(figsize=(8, 4))
8
9ax1.plot(months, revenue, color="tab:blue", marker="o", label="Revenue")
10ax1.set_xlabel("Month")
11ax1.set_ylabel("Revenue (thousand dollars)", color="tab:blue")
12ax1.tick_params(axis="y", labelcolor="tab:blue")
13
14ax2 = ax1.twinx()
15ax2.plot(months, conversion_rate, color="tab:red", marker="s", label="Conversion rate")
16ax2.set_ylabel("Conversion rate (%)", color="tab:red")
17ax2.tick_params(axis="y", labelcolor="tab:red")
18
19plt.title("Revenue and conversion rate")
20plt.tight_layout()
21plt.show()

The line that matters most for the secondary label is ax2.set_ylabel(...). If you accidentally call ax1.set_ylabel(...) twice, you will only update the primary axis and the right-side label will remain missing.

Keeping the two axes readable

Dual-axis charts can become confusing if both axes look the same. A good habit is to match each label color to its plotted line, as the example does with blue on the left and red on the right. You can also style tick labels the same way with tick_params.

This matters because the viewer should be able to answer two questions immediately:

  • Which line belongs to which y-axis
  • Which units apply to each measurement

If the scales are very different, a secondary axis is reasonable. If the scales are similar, two separate plots are often clearer than one chart with two y-axes.

Adding legends for both axes

Because ax1 and ax2 are separate axes, each one manages its own legend entries. To show one combined legend, collect the handles from both axes and pass them to a single legend call.

python
1import matplotlib.pyplot as plt
2
3days = [1, 2, 3, 4, 5]
4temperature = [2, 4, 5, 3, 6]
5rainfall = [12, 3, 0, 8, 5]
6
7fig, ax1 = plt.subplots()
8line1, = ax1.plot(days, temperature, color="tab:orange", label="Temperature")
9ax1.set_xlabel("Day")
10ax1.set_ylabel("Temperature (C)", color="tab:orange")
11
12ax2 = ax1.twinx()
13line2, = ax2.bar(days, rainfall, color="tab:green", alpha=0.35, label="Rainfall")
14ax2.set_ylabel("Rainfall (mm)", color="tab:green")
15
16ax1.legend([line1, line2], ["Temperature", "Rainfall"], loc="upper left")
17plt.tight_layout()
18plt.show()

This is not strictly required for the label itself, but it usually makes a dual-axis plot much easier to interpret.

Fine-tuning placement and layout

Most of the time, set_ylabel is enough. If the right-side label looks cramped, plt.tight_layout() or fig.tight_layout() usually fixes it by giving the figure more breathing room. You can also control label spacing with the labelpad argument.

python
ax2.set_ylabel("Rainfall (mm)", color="tab:green", labelpad=12)

That small adjustment is useful when tick labels are wide or when the figure is narrow.

Common Pitfalls

The most common mistake is creating ax2 = ax1.twinx() and then continuing to configure only ax1. Remember that the secondary axis is a different object with its own label, ticks, limits, and legend entries.

Another issue is forgetting layout management. When the figure is tight, the right-side label can be clipped off-screen. Call tight_layout or increase the figure size before assuming the label code failed.

It is also easy to misuse dual axes by plotting unrelated metrics that suggest a visual relationship when there is none. A secondary axis should be used sparingly and only when both series share the same x-axis context in a meaningful way.

Finally, avoid giving both axes identical colors and styles. Even if the code is technically correct, the chart becomes hard to read and the extra axis stops helping.

Summary

  • Create the right-side axis with ax2 = ax1.twinx().
  • Add the secondary y-axis label with ax2.set_ylabel(...).
  • Match label and tick colors to the plotted series for clarity.
  • Combine legend handles manually if you want one legend for both axes.
  • Use tight_layout() or labelpad when the secondary label looks cramped.

Course illustration
Course illustration

All Rights Reserved.