Secondary axis with twinx how to add to legend
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.
Introduction
matplotlib.axes.Axes.twinx() is useful when two series share the same x-axis but use very different y-axis scales. The part that usually surprises people is the legend: each Axes object manages its own artists, so calling legend() on only one axis does not automatically include lines drawn on the other axis.
Why the Legend Looks Incomplete
When you call ax.twinx(), Matplotlib creates a second Axes instance that is layered on top of the first one. Even though both axes share the x-axis, they are still separate plotting containers. That separation is why this common pattern produces an incomplete legend:
The legend will usually show only "Revenue" because ax.legend() collects labeled artists from ax, not from ax2.
Merge Handles from Both Axes
The most reliable fix is to gather legend handles and labels from both axes, then pass the combined lists into a single legend call.
This version is explicit and easy to reason about. You decide exactly which artists appear in the legend and in what order.
Use get_legend_handles_labels() for Larger Plots
If each axis contains multiple lines, bars, or other labeled artists, manually tracking every returned handle becomes tedious. In that case, let each axis report its labeled artists and then combine them.
This pattern scales well and is often the cleanest answer in reusable plotting functions.
Keep the Plot Readable
A secondary axis is easy to misuse. The legend may be fixed, but the chart can still be confusing if viewers cannot tell which series belongs to which axis.
A few practical rules help:
- use distinct colors for left-axis and right-axis series
- set each y-axis label color to match its data
- keep units explicit in axis labels and legend labels
- use
tight_layout()orconstrained_layout=Trueso labels do not overlap
You can also place the legend at the figure level if axis space is tight:
That approach is useful when you have a dense plot or want the legend centered above the entire figure instead of attached to one axis.
When a Secondary Axis Is the Wrong Tool
Sometimes the legend problem is a sign that the plot itself is doing too much. If the two series are not tightly related or the dual-axis scaling could mislead readers, separate subplots are often a better design.
Use twinx() when:
- the series share the same x-axis naturally
- the viewer benefits from seeing them aligned in time or sequence
- the different units can still be understood clearly
Use separate subplots when the extra axis adds more confusion than value.
Common Pitfalls
The main mistake is calling legend() on only one axis and expecting Matplotlib to collect artists from both ax and ax2. Another is combining handles correctly but forgetting to label the plotted artists, which leaves the legend empty or generic. Developers also create dual-axis plots without matching colors and labels to their respective axes, which makes the result harder to read even when the legend is technically correct. A final problem is using twinx() for unrelated metrics when separate subplots would communicate the data more honestly.
Summary
- '
twinx()creates a secondAxes, so legends are not merged automatically.' - '
ax.legend()only sees artists attached toax, notax2.' - Combine handles manually or use
get_legend_handles_labels()on both axes. - Match legend labels, line colors, and axis labels so the dual-axis plot stays readable.
- If the chart becomes confusing, use separate subplots instead of forcing a secondary axis.
Related reading
- Select DataFrame rows between two dates
- Select n records at random from a set of N
- Select Pandas rows based on list index
- Select row with most recent date per user
- Seeing escape characters when pressing the arrow keys in python shell
- Select rows in pandas MultiIndex DataFrame
- Selecting a row of pandas series/dataframe by integer index
- Selecting multiple columns in a Pandas dataframe
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.