在matplotlib网站的“图例指南”的"Legend location"部分,有一个小脚本,第9行是plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3, ncol=2, mode="expand", borderaxespad=0.)
。我看到传递给bbox_to_anchor
的所有元组都有2个元素,但是这个元素有4.如果元组通过有4个元素,每个元素意味着什么?
我在pyplot.legend
docs中查看了它,它说了bbox_transform
坐标。所以我环顾四周,发现matplotlib.transforms.Bbox
有一个static from_bounds(x0, y0, width, height)
。
我猜测4元组参数的设置基于此from_bounds
。我将脚本复制到Spyder,在Ipython控制台中执行了%matplotlib
,并更改了一些值。这似乎是有道理的,但是当我尝试将.102
更改为0.9
之类的内容时,传说并没有改变。我认为元组基于from_bounds
,我只是不知道为什么更改元组中的最后一个值什么也没做。
答案 0 :(得分:29)
你是对的,plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3)
中的4元组设置为(x0, y0, width, height)
,其中(x0,y0)
是边界框的左下角坐标。
虽然这些参数设置了图例的边界框,但图例的实际垂直尺寸会缩小到放置元素所需的大小。此外,它的位置仅与loc
参数一起确定。 loc参数设置边界框内图例的对齐方式,这样在某些情况下,更改height
时不会看到任何差异,例如,情节(2)和(4)。
答案 1 :(得分:10)
@ ImportanceOfBeingErnest的答案很棒。我想在图例框和边界框之间扩展alignment
的含义。这意味着图例框和边界框的参数loc
指示的不同位置将放在同一点。
例如,如果loc='center'
,图例框的中心和边界框将位于同一点。如果loc='center right'
,图例框的中间右侧和边界框将位于同一点。对于冗长... ...
让我们举一个具体的例子来说明这个想法,
bbox_to_anchor
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.patches as patches
locs = ['upper right', 'lower left', 'center left', 'lower center', 'center',
'right']
x0, y0, width, height = 0.5, 0.5, 0.1, 0.4
x = np.arange(0.1, 4, 0.1)
y = 1.0/x
fig = plt.figure(figsize=(10, 10))
idx = 1
for i in range(0, 2):
for j in range(0, 3):
ax = fig.add_subplot(3, 2, idx)
ax.plot(x, y, label=r'$\frac{1}{x}$')
ax.legend(loc=locs[idx-1], bbox_to_anchor=(x0, y0, width, height),
edgecolor='g', fontsize='large', framealpha=0.5,
borderaxespad=0)
ax.add_patch(
patches.Rectangle((x0, y0), width, height, color='r',
fill=False, transform=ax.transAxes)
)
ax.text(0.6, 0.2, s="loc = '{}'".format(locs[idx-1]),
transform=ax.transAxes)
idx += 1
plt.show()
在图像中,红色框是边界框,绿色框是图例框。每个子图中的loc
表示两个框之间的对齐关系。
bbox_to_anchor
当bbox_to_anchor
只有两个值时,边界框的宽度和高度设置为零。我们稍微修改上面的代码,
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.patches as patches
locs = ['upper right', 'lower left', 'center left', 'lower center', 'center',
'right']
x0, y0, width, height = 0.5, 0.5, 0, 0
x = np.arange(0.1, 4, 0.1)
y = 1.0/x
fig = plt.figure(figsize=(10, 10))
idx = 1
for i in range(0, 2):
for j in range(0, 3):
ax = fig.add_subplot(3, 2, idx)
ax.plot(x, y, label=r'$\frac{1}{x}$')
ax.legend(loc=locs[idx-1], bbox_to_anchor=(x0, y0, width, height),
edgecolor='g', fontsize='large', framealpha=0.5,
borderaxespad=0)
ax.add_patch(
patches.Rectangle((x0, y0), width, height, color='r',
fill=False, transform=ax.transAxes)
)
ax.text(0.6, 0.2, s="loc = '{}'".format(locs[idx-1]),
transform=ax.transAxes)
ax.plot(x0, y0, 'r.', markersize=8, transform=ax.transAxes)
idx += 1
plt.show()
现在,制作图像变为
上图中的红点表示边界框坐标位置。