Matplotlib:垂直扩展图例 [英] Matplotlib: expand legend vertically

查看:43
本文介绍了Matplotlib:垂直扩展图例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

borderaxespad=0. 会水平扩展它,但我找不到垂直扩展的等效项.

我使用的是 matplotlib 2.0

示例代码:

将 numpy 导入为 npx = np.linspace(0,2 * np.pi,100)数据= [np.sin(x * np.pi/float(el))对于范围在(1,5)中的el]无花果,ax = plt.subplots(1)对于枚举(数据)中的键,el:ax.plot(x, el, label=str(key))ax.legend(bbox_to_anchor=(1.04,1), loc="左上角", borderaxespad=0., mode='expand')plt.tight_layout(rect=[0,0,0.8,1])

哪个会产生:

解决方案

首先解释问题的输出:当使用 bbox_to_anchor 的 2-tuple 表示法时,创建了一个没有范围的边界框.mode="expand" 将图例水平扩展到这个边界框,它的扩展为零,有效地将其缩小到零大小.

问题是 mode="expand" 只会水平扩展图例.来自

I have a plot whose legend is anchored to the top-right corner: how can I expand the legend to fit the height of the chart?

borderaxespad=0. would expand it horizontally, but I could not find an equivalent to expand it vertically.

I am using matplotlib 2.0

Sample Code:

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

Which produces:

解决方案

First to explain the output from the question: When using the 2-tuple notation for bbox_to_anchor, a bounding box without extent is created. The mode="expand" will expand the legend horizontally into this bounding box, which has zero extend, effectively shrinking it to zero size.

The problem is that mode="expand" will expand the legend only horizontally. From the documentation:

mode : {"expand", None}
If mode is set to "expand" the legend will be horizontally expanded to fill the axes area (or bbox_to_anchor if defines the legend’s size).

For a solution you need to dig deep into the legend internals. First off you need to set the bbox-to-anchor with a 4-tuple, specifying also width and height of the bbox, bbox_to_anchor=(x0,y0,width,height), where all numbers are in normalized axes coordinates. Then you need to calculate the height of of the legend's _legend_box. Since there is some padding being set, you need to subtract that padding from the bounding box's height. In order to calculate the padding the current legend's fontsize must be known. All of this has to take place after the axes' position is last changed.

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

这篇关于Matplotlib:垂直扩展图例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆