这是一个非常好的问题,接受的答案指出了关键点(即
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)
![enter image description here](https://istack.dev59.com/KacDl.webp)
这基本上是令人满意的。但很容易发现图例与
ax2
的x轴刻度标签重叠。当
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)
![enter image description here](https://istack.dev59.com/OIhw5.webp)
因此,您可以看到ax2
和图例之间存在很大的差距。这不是我们想要的。与提问者一样,我们希望手动控制图例的位置。首先,我将使用bbox_to_anchor
的2号样式,就像答案中所做的那样。
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()
fig.legend([line1, line2], ['yep', 'nope'], loc='center', ncol=2,
bbox_to_anchor=[axbox.x0+0.5*axbox.width, axbox.y0-0.05])
![enter image description here](https://istack.dev59.com/GZhPo.webp)
就快做到了!但是完全是错的,因为图例的中心不在我们实际指的中心!解决这个问题的关键是,我们需要明确地将 bbox_transform
作为 fig.transFigure
通知。 默认情况下,将使用 Axes 的 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()
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)
![enter image description here](https://istack.dev59.com/9nF1a.webp)
作为替代方案,我们也可以使用4个数字样式的
bbox_to_anchor
来代替
loc
。这实际上是为图例指定一个真正的框,并且
loc
确实表示对齐方式!默认的
bbox_to_anchor
应该只是
[0,0,1,1]
,意味着整个图形框!这四个数字分别表示
x0,y0,width,height
。它与
指定共享颜色条的cax非常相似!因此,您可以轻松将
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()
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)
![enter image description here](https://istack.dev59.com/NKvO2.webp)