Sometimes you will have a grid of subplots, and you want to have a single legend that describes all the lines for each of the subplots as in the following image.
In order to do this, you will need to create a global legend for the figure
instead of creating a legend at the axes level (which will create a separate
legend for each subplot). This is achieved by calling fig.legend() as can be
seen in the code for the following code.
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(10,4))
fig.suptitle('Example of a Single Legend Shared Across Multiple Subplots')
# The data
x = [1, 2, 3]
y1 = [1, 2, 3]
y2 = [3, 1, 3]
y3 = [1, 3, 1]
y4 = [2, 2, 3]
# Labels to use in the legend for each line
line_labels = ["Line A", "Line B", "Line C", "Line D"]
# Create the sub-plots, assigning a different color for each line.
# Also store the line objects created
l1 = ax1.plot(x, y1, color="red")[0]
l2 = ax2.plot(x, y2, color="green")[0]
l3 = ax3.plot(x, y3, color="blue")[0]
l4 = ax3.plot(x, y4, color="orange")[0] # A second line in the third subplot
# Create the legend
fig.legend([l1, l2, l3, l4], # The line objects
labels=line_labels, # The labels for each line
loc="center right", # Position of legend
borderaxespad=0.1, # Small spacing around legend box
title="Legend Title" # Title for the legend
)
# Adjust the scaling factor to fit your legend text completely outside the plot
# (smaller value results in more space being made for the legend)
plt.subplots_adjust(right=0.85)
plt.show()
Something to note about the above example is the following:
l1 = ax1.plot(x, y1, color="red")[0]
When plot() is called, it returns a list of line2D objects. In this case it
just returns a list with one single line2D object, which is extracted with the
[0] indexing, and stored in l1.
A list of all the line2D objects that we are interested in including in the
legend need to be passed on as the first argument to fig.legend(). The second
argument to fig.legend() is also necessary. It is supposed to be a list of
strings to use as the labels for each line in the legend.
The other arguments passed on to fig.legend() are purely optional, and just
help with fine-tuning the aesthetics of the legend.