Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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 give each Matplotlib subplot its own legend, add a label to each plotted series and call ax.legend() on that subplot’s Axes. To show one legend for several subplots, collect the relevant handles and labels and pass them to fig.legend().

Give each subplot its own legend

In Matplotlib, each subplot is an Axes. Label the plotted artists, then call legend() on the Axes that should display those entries:

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() uses artists and labels from that Axes. This is appropriate when panels have different series or when readers should interpret each panel independently.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Put one shared legend on the figure

When entries from multiple subplots belong in one legend, attach it to the Figure with fig.legend(). You can gather entries from every Axes, or from only the Axes whose artists you want represented:

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)

Here fig is the Figure returned by plt.subplots(). Passing the lists explicitly makes the source of the shared entries clear and lets you select or reorder them before creating the legend. Use a Figure legend when the entries describe the figure as a whole; avoid leaving duplicate Axes legends visible unless that repetition is deliberate.

Why a legend can be empty or miss entries

With no arguments, legend() automatically discovers eligible handles and their associated labels on the object it belongs to. If you call ax.legend(), discovery is limited to that Axes; it does not automatically combine entries from other subplots.

  • Check that artists have labels. Set label="Series A" when plotting, or call an artist’s set_label() before creating the legend.
  • Check for underscore-prefixed labels. Labels beginning with an underscore are excluded from automatic legend discovery. Many artists use underscore-prefixed labels by default, so a plot without explicit labels may produce no entries.
  • Choose handles explicitly when needed. Use get_legend_handles_labels() to inspect an Axes’ entries, or pass selected handles and labels directly to ax.legend() or fig.legend().
  • Use a proxy artist for unsupported artist types. Some artists do not have a default legend handler. The Matplotlib legend guide describes using a separate proxy artist to represent such an item.

Place legends without obscuring the plots

An Axes legend is positioned relative to its subplot; a Figure legend is positioned relative to the whole figure. Choose the owner that matches the scope of the entries, then adjust placement to suit the available space.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • For an Axes legend: use loc to choose a location within or around that subplot. For finer positioning, bbox_to_anchor can place an Axes legend using figure coordinates.
  • For a Figure legend: the Matplotlib legend guide shows outside placements with loc values beginning with "outside" when using constrained layout, such as "outside upper center".
  • For a wider legend: set ncols to the desired number of columns. The current Figure API retains ncol as a backward-compatible spelling but discourages it.

For example, the earlier shared-legend code uses layout="constrained" in plt.subplots() and places the Figure legend above the subplot grid. If the legend overlaps data or labels, try a different location, move it outside the grid, or change the number of columns.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Matplotlib version note

The stable documentation consulted identifies Matplotlib 3.11.2. Legend APIs and layout behavior may change between releases; if an example behaves differently in your installation, check the documentation for your installed version. See the Matplotlib legend guide, the Figure.legend API reference, and the Axes.legend API reference.

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.