matplotlib 垂直展开图例

ne5o7dgx  于 2023-05-18  发布在  其他
关注(0)|答案(2)|浏览(128)

我有一个图,其图例锚定在右上角:如何扩展图例以适应图表的高度?
borderaxespad=0.会水平扩展它,但我找不到一个等效的垂直扩展它。
我使用的是matplotlib 2.0
样本代码:

import numpy as np

x = np.linspace(0, 2*np.pi, 100)
data = [np.sin(x * np.pi/float(el)) for el in range(1, 5)]

fig, ax = plt.subplots(1)
for key, el in enumerate(data):
    ax.plot(x, el, label=str(key))
ax.legend(bbox_to_anchor=(1.04,1), loc="upper left", borderaxespad=0., mode='expand')
plt.tight_layout(rect=[0,0,0.8,1])

生产:

t1qtbnec

t1qtbnec1#

首先解释问题的输出:当对bbox_to_anchor使用二元组表示法时,将创建一个不带范围的边界框。mode="expand"会将图例水平扩展到这个边界框中,该边界框具有零扩展,从而有效地将其缩小到零大小。
问题是mode="expand"只会水平展开图例。来自文档:
mode:{“expand”,None}
如果模式设置为“展开”,则图例将被水平展开以填充轴区域(或者bbox_to_锚,如果定义图例的大小)。
要获得解决方案,您需要深入挖掘图例内部。首先,您需要使用4元组设置bbox-to-锚,同时指定bbox的宽度和高度bbox_to_anchor=(x0,y0,width,height),其中所有数字都在归一化坐标轴中。然后,您需要计算图例的_legend_box的高度。由于设置了一些填充,所以需要从边界框的高度中减去该填充。为了计算填充,必须知道当前图例的字体大小。所有这些都必须在轴的位置上次更改之后进行。

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 2*np.pi, 100)
data = [np.sin(x * np.pi/float(el)) for el in range(1, 5)]

fig, ax = plt.subplots(1)
for key, el in enumerate(data):
    ax.plot(x, el, label=str(key))

# legend:    
leg = ax.legend(bbox_to_anchor=(1.04,0.0,0.2,1), loc="lower left",
                borderaxespad=0, mode='expand')

plt.tight_layout(rect=[0,0,0.8,1])

# do this after calling tight layout or changing axes positions in any way:
fontsize = fig.canvas.get_renderer().points_to_pixels(leg._fontsize)
pad = 2 * (leg.borderaxespad + leg.borderpad) * fontsize
leg._legend_box.set_height(leg.get_bbox_to_anchor().height-pad)

plt.show()

at0kjp5o

at0kjp5o2#

labelspacing可能是你要找的?

fig, ax = plt.subplots(1)
for key, el in enumerate(data):
    ax.plot(x, el, label=str(key))
ax.legend(labelspacing=8, loc=6, bbox_to_anchor=(1, 0.5))
plt.tight_layout(rect=[0, 0, 0.9, 1])

这不是自动的,但你可能会发现与figsize(这里也是8)的一些关系。
loc=6, bbox_to_anchor=(1, 0.5)将使图例位于图的右侧居中。
其给出:

相关问题