Matplotlib:垂直展开图例

时间:2017-10-12 13:12:24

标签: python matplotlib

我有一个情节,其图例固定在右上角:如何展开图例以适应图表的高度?

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])

产生:

enter image description here

2 个答案:

答案 0 :(得分:3)

首先解释问题的输出:当对bbox_to_anchor使用2元组表示法时,会创建一个没有范围的边界框。 mode="expand"会将图例水平扩展到此边界框中,该边框没有延伸,有效地将其缩小到零大小。

问题是mode="expand"只能水平扩展图例。 来自the documentation

  

mode:{“展开”,无}   如果模式设置为"展开"图例将水平展开以填充轴区域(如果定义图例的大小,则为bbox_to_anchor)。

对于解决方案,您需要深入了解传奇内幕。首先,您需要使用4元组设置bbox-to-anchor,同时指定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()

enter image description here

答案 1 :(得分:1)

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)会将您的传奇中心放在情节的右侧。

给出了: expand legend matplotib