[PYTHON] matplotlib legend layout notes

Display legend, select curve

If you do not include any options in ʻax.legend () `.

python


import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 101)
y1 = np.sin(x * np.pi)
y2 = np.cos(x * 2 * np.pi) * 0.5

fig = plt.figure()
ax = fig.add_subplot(111)

#Specify the curve name used in the legend with the label option
ax.plot(x, y1, c="r", label="$\mathrm{sin}(x)$")
ax.plot(x, y2, c="b", label="$0.5 \mathrm{cos}(2x)$")
ax.grid(axis='both')

#Displaying the legend
ax.legend()

image.png

The exact same figure as above is drawn using the curve information and label information acquired by ʻax.get_legend_handles_labels () `, as shown below.

python


ax.plot(x, y1, c="r", label="$\mathrm{sin}(x)$")
ax.plot(x, y2, c="b", label="$0.5 \mathrm{cos}(2x)$")
ax.grid(axis='both')

#List of curve objects with label specified for hands,
#labs contains a list of corresponding labels
hans, labs = ax.get_legend_handles_labels()

#Displaying the legend
ax.legend(handles=hans, labels=labs)

Curve information and label information acquired by ʻax.get_legend_handles_labels () `can also be specified as follows.

python


l1 = ax.plot(x, y1, c="r")
l2 = ax.plot(x, y2, c="b")
ax.grid(axis='both')

#Displaying the legend
#Since l1 and l2 are list types,+Combine with operators
#In this case, handles can be omitted.
ax.legend(handles=l1+l2, labels=["$\mathrm{sin}(x)$", "$0.5 \mathrm{cos}(2x)$"])

For example, if you want to reverse the order of the legends, do as follows.

python


x = np.linspace(-3,3,101)

fig = plt.figure(figsize=(10,5))
#Left figure
ax1 = fig.add_subplot(121)
#Right figure
ax2 = fig.add_subplot(122)
for i in np.linspace(-1,1,5):
    ax1.plot(x, np.sin(x)+i, label=str(i))
    ax2.plot(x, np.sin(x)+i, label=str(i))

#Get legend information
hans, labs = ax1.get_legend_handles_labels()
#Display of legend on the left
ax1.legend(handles=hans, labels=labs, fontsize=8)
#Display of legend on the right (reverse order)
ax2.legend(handles=hans[::-1], labels=labs[::-1], fontsize=8)

image.png

Legend layout

loc option

Positions within the axis are defined for numbers from 1 to 9. You can also specify the corresponding character string ("upper right", "upper left", etc.).

python


fig = plt.figure(figsize=(10,10))
for i in range(1,9+1):
    ax = fig.add_subplot(330+i)

    #Even if you empty the list needed for drawing
    #The style of the curve is defined and reflected in the legend.
    ax.plot([], [], c="r", label="sin")
    ax.plot([], [], c="b", label="cos")
    #Add green text (centered on axis)
    ax.text(0.5, 0.5, "loc={}".format(i),
            c="g", fontsize=30,
            horizontalalignment="center",
            verticalalignment="center", )
    #Drawing a legend with loc specified
    ax.legend(loc=i)

image.png

Drawing outside the axis (bbox_to_anchor), changing the number of columns (ncol)

To make it easier to understand, I added a green marker to the coordinates specified by bbox_to_anchor.

python


fig = plt.figure(figsize=(10,10))

#upper left
ax = fig.add_subplot(321)
ax.plot([], [], c="r", label="sin")
ax.plot([], [], c="b", label="cos")
#Draw a legend at the top of axis
#Reference point at the bottom center of the legend window
#The coordinates of the reference point are the center of the axis in the horizontal direction and slightly above the upper side of the axis in the vertical direction.
#Apply 2-column display with ncol
ax.legend(loc="lower center", bbox_to_anchor=(0.5, 1.02,), borderaxespad=0, ncol=2)
# bbox_to_Add a green marker at the anchor position
# clip_on=Allows drawing outside the axis with False
# transform=ax.In transAxes, the lower left and upper right coordinates of axis are(0,0)(1,1)Apply the system that becomes.
circle = plt.Circle((0.5, 1.02,), 0.01, color='g', clip_on=False, transform=ax.transAxes)
ax.add_artist(circle)

#Upper right
ax = fig.add_subplot(322)
ax.plot([], [], c="r", label="sin")
ax.plot([], [], c="b", label="cos")
#Draw a legend in the upper right corner of axis
#Reference point in the upper left of the legend window
#The coordinates of the reference point are slightly to the right of the right side of the axis in the horizontal direction and the upper side of the axis in the vertical direction.
ax.legend(loc="upper left", bbox_to_anchor=(1.02, 1.0,), borderaxespad=0)
circle = plt.Circle((1.02, 1.0,), 0.01, color='g', clip_on=False, transform=ax.transAxes)
ax.add_artist(circle)

#Middle right
ax = fig.add_subplot(324)
ax.plot([], [], c="r", label="sin")
ax.plot([], [], c="b", label="cos")
#Draw a legend in the middle right of axis
#Reference point in the middle left of the legend window
#The coordinates of the reference point are slightly to the right of the right side of the axis in the horizontal direction and the center of the axis in the vertical direction.
ax.legend(loc="center left", bbox_to_anchor=(1.02, 0.5,), borderaxespad=0)
circle = plt.Circle((1.02, 0.5,), 0.01, color='g', clip_on=False, transform=ax.transAxes)
ax.add_artist(circle)

#Lower left
ax = fig.add_subplot(325)
ax.plot([], [], c="r", label="sin")
ax.plot([], [], c="b", label="cos")
#Draw a legend at the bottom of axis
#Reference point on the center of the legend window
#The coordinates of the reference point are the center of the axis in the horizontal direction and more than the bottom side of the axis in the vertical direction.
ax.legend(loc="upper center", bbox_to_anchor=(0.5, -0.1,), borderaxespad=0, ncol=2)
circle = plt.Circle((0.5, -0.1,), 0.01, color='g', clip_on=False, transform=ax.transAxes)
ax.add_artist(circle)

#Lower right
ax = fig.add_subplot(326)
ax.plot([], [], c="r", label="sin")
ax.plot([], [], c="b", label="cos")
#Draw a legend at the bottom right of axis
#Reference point at the bottom left of the legend window
#The coordinates of the reference point are slightly to the right of the right side of the axis in the horizontal direction and the lower side of the axis in the vertical direction.
#Apply 2-column display with ncol
ax.legend(loc="lower left", bbox_to_anchor=(1.02, 0.0,), borderaxespad=0)
circle = plt.Circle((1.02, 0.0,), 0.01, color='g', clip_on=False, transform=ax.transAxes)
ax.add_artist(circle)

image.png

If you change the code above from borderaxespad = 0 to borderaxespad = 1, it will look like the figure below. This number is defined as a relative value with the number of points specified by font-size as 1.

image.png

2-axis graph legend

Combine the above two.

python


x = np.linspace(-3,3,101)
y1 = np.sin(x * np.pi)
y2 = np.cos(x * 2 * np.pi) * 0.5
z  = np.tan(x * np.pi)

fig = plt.figure(figsize=(10,5))

#Left figure
#Draw the legend for each axis independently
ax = fig.add_subplot(131)
ax.plot(x, y1, c="r", label="$\mathrm{sin}(x)$")
ax.plot(x, y2, c="b", label="$0.5 \mathrm{cos}(2x)$")
ax.grid(axis='both')
#Displaying the legend for the 1st axis graph
ax.legend(loc="upper left", bbox_to_anchor=(1.2, 1.0))
#2nd axis
ax2 = ax.twinx()
ax2.plot(x, z, "g", marker="o", lw=0, ms=2, label = '$\mathrm{tan}(x)$')
ax2.set_ylim(-3,3)
#Displaying the legend for the graph on the second axis
ax2.legend(loc="lower left", bbox_to_anchor=(1.2, 0.0))

#Right figure
#Integrate the legend of the two axes
ax = fig.add_subplot(133)
ax.plot(x, y1, c="r", label="$\mathrm{sin}(x)$")
ax.plot(x, y2, c="b", label="$0.5 \mathrm{cos}(2x)$")
ax.grid(axis='both')
#1st axis legend information retention
hans1, labs1 = ax.get_legend_handles_labels()
#2nd axis
ax2 = ax.twinx()
ax2.plot(x, z, "g", marker="o", lw=0, ms=2, label = '$\mathrm{tan}(x)$')
ax2.set_ylim(-3,3)
#2nd axis legend information retention
hans2, labs2 = ax2.get_legend_handles_labels()
#Displaying the legend
ax.legend(hans1+hans2, labs1+labs2, loc="upper left", bbox_to_anchor=(1.2, 1.0))

image.png

Recommended Posts

matplotlib legend layout notes
Translucent matplotlib legend
Notes on using matplotlib on the server
Jupyter, numpy, matplotlib notes used in reports