Matplotlib:调整图例位置/位置 [英] Matplotlib: Adjust legend location/position

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

问题描述

我正在创建一个包含多个子图的图形.这些子图之一给我带来了麻烦,因为没有任何轴角或中心是免费的(或可以释放)用于放置图例.我想做的是将图例放置在左上"和左中"位置之间的某个位置,同时使它和y轴之间的填充与其他子图中的图例(即使用预定义的图例位置关键字之一放置).

I'm creating a figure with multiple subplots. One of these subplots is giving me some trouble, as none of the axes corners or centers are free (or can be freed up) for placing the legend. What I'd like to do is to have the legend placed somewhere in between the 'upper left' and 'center left' locations, while keeping the padding between it and the y-axis equal to the legends in the other subplots (that are placed using one of the predefined legend location keywords).

我知道我可以使用loc=(x,y)指定自定义位置,但是后来我不知道如何使图例和y轴之间的填充等于其他图例所使用的填充.是否可以以某种方式使用第一个图例的borderaxespad属性?尽管我没有成功地使它生效.

I know I can specify a custom position by using loc=(x,y), but then I can't figure out how to get the padding between the legend and the y-axis to be equal to that used by the other legends. Would it be possible to somehow use the borderaxespad property of the first legend? Though I'm not succeeding at getting that to work.

任何建议都将受到欢迎!

Any suggestions would be most welcome!

这是问题的(非常简化)说明:

Here is a (very simplified) illustration of the problem:

import matplotlib.pyplot as plt

fig, ax = plt.subplots(1, 2, sharex=False, sharey=False)
ax[0].axhline(y=1, label='one')
ax[0].axhline(y=2, label='two')
ax[0].set_ylim([0.8,3.2])
ax[0].legend(loc=2)

ax[1].axhline(y=1, label='one')
ax[1].axhline(y=2, label='two')
ax[1].axhline(y=3, label='three')
ax[1].set_ylim([0.8,3.2])
ax[1].legend(loc=2)

plt.show()

我想要的是右图中的图例有些向下移动,因此不再与线条重叠. 作为最后的选择,我可以更改轴限制,但是我非常想避免这种情况.

What I'd like is that the legend in the right plot is moved down somewhat so it no longer overlaps with the line. As a last resort I could change the axis limits, but I would very much like to avoid that.

推荐答案

在此上花了太多时间之后,我提出了以下令人满意的解决方案(

After spending way too much time on this, I've come up with the following satisfactory solution (the Transformations Tutorial definitely helped):

bapad = plt.rcParams['legend.borderaxespad']
fontsize = plt.rcParams['font.size']
axline = plt.rcParams['axes.linewidth']  #need this, otherwise the result will be off by a few pixels
pad_points = bapad*fontsize + axline  #padding is defined in relative to font size
pad_inches = pad_points/72.0  #convert from points to inches
pad_pixels = pad_inches*fig.dpi  #convert from inches to pixels using the figure's dpi

然后,我发现以下两项工作均具有相同的填充值:

Then, I found that both of the following work and give the same value for the padding:

# Define inverse transform, transforms display coordinates (pixels) to axes coordinates
inv = ax[1].transAxes.inverted()
# Inverse transform two points on the display and find the relative distance
pad_axes = inv.transform((pad_pixels, 0)) - inv.transform((0,0))  
pad_xaxis = pad_axes[0]

# Find how may pixels there are on the x-axis
x_pixels = ax[1].transAxes.transform((1,0)) - ax[1].transAxes.transform((0,0))
# Compute the ratio between the pixel offset and the total amount of pixels 
pad_xaxis = pad_pixels/x_pixels[0]

然后使用以下命令设置图例:

And then set the legend with:

ax[1].legend(loc=(pad_xaxis,0.6))

情节:

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

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