这是一个很好的问题,接受的答案表明了关键(即loc
表示对齐和bbox_to_anchor
表示位置)。我也尝试了一些代码,并想强调有时需要明确指定才能达到预期效果的属性的重要性。bbox_transform
下面我将向您展示我的发现fig.legend
。ax.legend
应该非常相似,loc
并且bbox_to_anchor
工作方式相同。
使用默认设置时,我们将有以下内容。
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(6,4), sharex=True)
x = np.linspace(0, np.pi, 100)
line1, = ax1.plot(x, np.cos(3*x), color='red')
line2, = ax2.plot(x, np.sin(4*x), color='green')
fig.legend([line1, line2], ['yep', 'nope'], loc='lower center', ncol=2)
这基本上是令人满意的。但很容易发现,图例与 .x 轴刻度标签重叠ax2
。figsize
当和/或dpi
图形发生变化时,这个问题将变得更加严重,请参见下文。
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(6,12), sharex=True, facecolor='w', gridspec_kw={'hspace':0.01})
x = np.linspace(0, np.pi, 100)
line1, = ax1.plot(x, np.cos(3*x), color='red')
line2, = ax2.plot(x, np.sin(4*x), color='green')
fig.legend([line1, line2], ['yep', 'nope'], loc='lower center', ncol=2)
ax2
所以你看到和传说之间有很大的差距。这不是我们想要的。像提问者一样,我们想手动控制图例的位置。首先,我将使用 2-number 样式,bbox_to_anchor
就像答案一样。
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(6,12), sharex=True, facecolor='w', gridspec_kw={'hspace':0.01})
x = np.linspace(0, np.pi, 100)
line1, = ax1.plot(x, np.cos(3*x), color='red')
line2, = ax2.plot(x, np.sin(4*x), color='green')
axbox = ax2.get_position()
# to place center point of the legend specified by loc at the position specified by bbox_to_anchor.
fig.legend([line1, line2], ['yep', 'nope'], loc='center', ncol=2,
bbox_to_anchor=[axbox.x0+0.5*axbox.width, axbox.y0-0.05])
差不多好了!但这是完全错误的,因为传说的中心并不是我们真正意思的中心!解决这个问题的关键是我们需要明确告知bbox_transform
as fig.transFigure
。默认情况下无,将使用轴的 transAxes 变换。这是可以理解的,因为我们大部分时间都会使用ax.legend()
.
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(6,12), sharex=True, facecolor='w', gridspec_kw={'hspace':0.01})
x = np.linspace(0, np.pi, 100)
line1, = ax1.plot(x, np.cos(3*x), color='red')
line2, = ax2.plot(x, np.sin(4*x), color='green')
axbox = ax2.get_position()
# to place center point of the legend specified by loc at the position specified by bbox_to_anchor!
fig.legend([line1, line2], ['yep', 'nope'], loc='center', ncol=2,
bbox_to_anchor=[axbox.x0+0.5*axbox.width, axbox.y0-0.05], bbox_transform=fig.transFigure)
作为替代方案,我们也可以bbox_to_anchor
为loc
. 这本质上是为图例指定一个真实的框,并且loc
真正表示对齐!默认bbox_to_anchor
应该只是[0,0,1,1]
,意思是整个图形框!四个数字x0,y0,width,height
分别代表 。这与为共享颜色条指定 cax非常相似!因此,您可以轻松地更改y0
稍微低于axbox.y0
并loc
进行相应调整。
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(6,12), sharex=True, facecolor='w', gridspec_kw={'hspace':0.01})
x = np.linspace(0, np.pi, 100)
line1, = ax1.plot(x, np.cos(3*x), color='red')
line2, = ax2.plot(x, np.sin(4*x), color='green')
axbox = ax2.get_position()
# to place center point specified by loc at the position specified by bbox_to_anchor!
fig.legend([line1, line2], ['yep', 'nope'], loc='lower center', ncol=2,
bbox_to_anchor=[0, axbox.y0-0.05,1,1], bbox_transform=fig.transFigure)