放置图例 (bbox_to_anchor)
使用 plt.legend 的 loc 参数将图例定位在轴的边界框内。
例如,loc="upper right" 将图例放在边界框的右上角,默认情况下,坐标轴坐标(或边界框符号 (x0, y0, width, height) = (0, 0, 1, 1))的范围从 (0, 0) 到 (1, 1)。
要将图例放置在轴边界框之外,可以指定图例左下角轴坐标的元组(x0, y0)。
plt.legend(loc=(1.04, 0))
一种更通用的方法是使用bbox_to_anchor争论。可以限制自己只提供 bbox 的 (x0, y0) 部分。这将创建一个零跨度框,图例将从该框向loc 参数指定的方向展开。例如。,
plt.legend(bbox_to_anchor=(1.04, 1), loc="左上角")
将图例放置在轴外,这样图例的左上角就位于轴坐标中的位置(1.04, 1)。
下面给出了更多示例,其中还显示了不同参数之间的相互作用,如 mode 和 ncols。
l1 = plt.legend(bbox_to_anchor=(1.04, 1), borderaxespad=0)
l2 = plt.legend(bbox_to_anchor=(1.04, 0), loc="lower left", borderaxespad=0)
l3 = plt.legend(bbox_to_anchor=(1.04, 0.5), loc="center left", borderaxespad=0)
l4 = plt.legend(bbox_to_anchor=(0, 1.02, 1, 0.2), loc="lower left",
mode="expand", borderaxespad=0, ncol=3)
l5 = plt.legend(bbox_to_anchor=(1, 0), loc="lower right",
bbox_transform=fig.transFigure, ncol=3)
l6 = plt.legend(bbox_to_anchor=(0.4, 0.8), loc="upper right")
有关如何解释 bbox_to_anchor 的 4 元组参数的详细信息,如 l4 中所示,可以在 this question 中找到。 mode="expand" 在 4 元组给定的边界框内水平扩展图例。有关垂直展开的图例,请参阅this question。
有时在图形坐标而不是轴坐标中指定边界框可能很有用。这在上面的示例 l5 中显示,其中 bbox_transform 参数用于将图例放在图的左下角。
后期处理
将图例放置在坐标轴之外通常会导致出现完全或部分位于图形画布之外的不良情况。
这个问题的解决方案是:
上述案例的比较:
备择方案
人物传奇
可以使用图例代替轴,matplotlib.figure.Figure.legend。这对于不需要特殊参数的 Matplotlib 2.1 版或更高版本特别有用
fig.legend(loc=7)
为人物不同轴上的所有艺术家创造一个传奇。图例使用 loc 参数放置,类似于它放置在轴内的方式,但参考整个图形 - 因此它会自动位于轴外。剩下的就是调整子图,使图例和轴之间没有重叠。重点在这里《调整子图参数》从上面会有所帮助。一个例子:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2*np.pi)
colors = ["#7aa0c4", "#ca82e1", "#8bcd50", "#e18882"]
fig, axes = plt.subplots(ncols=2)
for i in range(4):
axes[i//2].plot(x, np.sin(x+i), color=colors[i], label="y=sin(x + {})".format(i))
fig.legend(loc=7)
fig.tight_layout()
fig.subplots_adjust(right=0.75)
plt.show()
专用子图轴内的图例
使用 bbox_to_anchor 的替代方法是将图例放在其专用的子图轴 (lax) 中。
由于图例子图应该小于图,我们可以在轴创建时使用gridspec_kw={"width_ratios":[4, 1]}。
我们可以隐藏轴lax.axis("off"),但我们仍然放入图例。图例句柄和标签需要通过h, l = ax.get_legend_handles_labels()从真实图中获取,然后可以提供给lax子图中的图例,@987654380 @.下面是一个完整的例子。
import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = 6, 2
fig, (ax, lax) = plt.subplots(ncols=2, gridspec_kw={"width_ratios":[4, 1]})
ax.plot(x, y, label="y=sin(x)")
....
h, l = ax.get_legend_handles_labels()
lax.legend(h, l, borderaxespad=0)
lax.axis("off")
plt.tight_layout()
plt.show()
这会产生一个视觉上与上面的图非常相似的图:
我们也可以使用第一个轴来放置图例,但是使用图例轴的bbox_transform,
ax.legend(bbox_to_anchor=(0, 0, 1, 1), bbox_transform=lax.transAxes)
lax.axis("off")
在这种方法中,我们不需要从外部获取图例句柄,但我们需要指定bbox_to_anchor参数。
进一步阅读和注意事项: