For a separate legend on each Matplotlib subplot, label the plotted artists and call ax.legend() on each Axes. To combine entries from several subplots into one legend, gather their handles and labels and call fig.legend().
Add a separate legend to each subplot
In Matplotlib, each subplot is an Axes. Give each plotted series a label, then call legend() on the Axes that should display it. The following example creates two subplots with independent legends:
As an Amazon Associate I earn from qualifying purchases.
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(1, 2, layout="constrained")
ax1.plot([1, 2, 3], [2, 4, 3], label="Series A")
ax1.plot([1, 2, 3], [1, 3, 5], label="Series B")
ax1.legend()
ax2.plot([1, 2, 3], [4, 2, 3], label="Series C")
ax2.legend()
plt.show()
Each call to ax.legend() discovers eligible labeled artists on that Axes. For more on automatic discovery, see the Matplotlib legend guide.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Make one legend for multiple subplots
Use fig.legend() when the entries describe the figure as a whole rather than an individual panel. To include entries from multiple Axes, collect their handles and labels, then pass those lists to the Figure legend:
#1 Best Overall
handles, labels = [], []
for ax in fig.axes:
ax_handles, ax_labels = ax.get_legend_handles_labels()
handles.extend(ax_handles)
labels.extend(ax_labels)
fig.legend(handles, labels, loc="outside upper center", ncols=2)
This example assumes fig already refers to the Figure containing the plotted Axes. You can also pass selected handles and labels explicitly if you want to include only particular artists. The Figure.legend API documents the available arguments.
A shared legend is separate from legends attached to individual Axes. If you use it, omit per-Axes legends unless you intentionally want the same information repeated.
Rank #2
Choose the legend scope and location
The right method depends on what the labels describe and where the legend should sit:
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →| Approach | Scope | Placement |
|---|---|---|
ax.legend() |
Artists discovered on one Axes, or handles and labels supplied for that legend | Relative to the Axes by default |
fig.legend() |
Artists selected for the Figure, including entries combined from several Axes | Relative to the Figure by default; the legend guide documents outside locations with constrained layout |
For an Axes legend positioned beyond its plot area, use bbox_to_anchor to position it in figure coordinates. For a Figure legend outside the subplot grid, the legend guide shows loc values beginning with outside alongside constrained layout. If a legend has many entries, ncols can arrange them in columns. The current Figure.legend API retains ncol as a backward-compatible spelling but discourages it.
Rank #3
Fix an empty or incomplete legend
With no arguments, legend() looks for handles and their associated labels on its owning Axes. Labels beginning with an underscore are excluded; many artists use underscore-prefixed labels by default. If the legend is empty or misses an item, give the artist a non-underscore label when plotting or set one before calling legend():
line, = ax.plot(x, y)
line.set_label("Measured values")
ax.legend()
You can inspect the automatically discovered entries with ax.get_legend_handles_labels(). If a plotted artist type has no default legend handler, the official legend guide describes using a proxy artist: a separate representative artist supplied to the legend instead of relying on the plotted object itself.
Rank #4
Version note
The code uses Matplotlib’s documented constrained-layout and Figure legend options. The current stable documentation identifies Matplotlib 3.11.2; if you are using a different release, check its legend guide and Figure.legend API for version-specific behavior.
Quick Recap
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.




