How to put the legend outside the plot
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
In matplotlib, the legend is placed inside the plot area by default, which can overlap with data. To move it outside, use the bbox_to_anchor parameter in plt.legend() to position the legend relative to the axes, and loc to set the anchor point. You typically also need to adjust the figure layout so the legend is not clipped. The same technique works with seaborn since it uses matplotlib under the hood.
Basic Legend Outside the Plot
bbox_to_anchor=(1.05, 1) places the anchor point at x=1.05 (just outside the right edge) and y=1 (top). loc="upper left" aligns the upper-left corner of the legend box to that anchor point.
Common Positions
The ncol parameter arranges legend entries in multiple columns, useful for horizontal legends below or above the plot.
Preventing Legend Clipping
When the legend is outside the axes, it may be clipped by the figure boundary:
bbox_inches="tight" in savefig() automatically expands the figure boundary to include the legend.
With Subplots
fig.legend() creates a figure-level legend instead of per-axes legends.
Seaborn Plots
Seaborn returns matplotlib axes, so the same technique works:
sns.move_legend() (seaborn 0.12+) is the cleanest way. For older versions, use ax.legend(bbox_to_anchor=...).
Customizing Legend Appearance
Saving with the Legend Included
When saving to a file, the legend outside the axes is often cut off:
Always use bbox_inches="tight" when saving plots with external legends.
Common Pitfalls
- Legend clipped in saved files:
plt.savefig()withoutbbox_inches="tight"clips content outside the figure boundary. Always passbbox_inches="tight"when the legend is outside the axes. - Confusing
bbox_to_anchorcoordinates: The values are in axes coordinates (0-1 is inside the axes).(1, 1)is the top-right corner of the axes. Values above 1 or below 0 are outside the axes. locmisunderstanding:locsets which part of the legend box aligns to the anchor.loc="upper left"withbbox_to_anchor=(1, 1)puts the legend's upper-left corner at the axes' top-right corner.tight_layoutconflicting withconstrained_layout: Using bothtight_layout()andconstrained_layout=Truetogether produces a warning and unpredictable results. Use one or the other.- Legend overlapping subplots: For multi-subplot figures, per-axes legends can overlap adjacent plots. Use a single
fig.legend()positioned outside all subplots instead.
Summary
- Use
ax.legend(bbox_to_anchor=(x, y), loc="...")to position the legend outside the plot - Common positions: right
(1.05, 1), below(0.5, -0.15), above(0.5, 1.15) - Use
ncolfor horizontal legend layouts below or above the plot - Always use
bbox_inches="tight"insavefig()to prevent clipping - Use
fig.legend()for a single legend shared across multiple subplots - Use
sns.move_legend()for seaborn plots (seaborn 0.12+)
Related reading
- How to put the legend outside the plot
- How to query distinct from AWS log insights
- How to re-partition pyspark dataframe?
- How to read a csv file from an s3 bucket using Pandas in Python
- How to quickly and conveniently create a one element arraylist
- How to quickly stop seda in camel
- How to read a Parquet file into Pandas DataFrame?
- How to read a .xlsx file using the pandas Library in iPython?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the 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.