Matplotlib: Adjust legend location/position

我只是一个虾纸丫 提交于 2019-12-03 02:30:30

I saw the answer you posted and tried it out. The problem however is that it is also depended on the figure size.

Here's a new try:

import numpy
import matplotlib.pyplot as plt


x = numpy.linspace(0, 10, 10000)
y = numpy.cos(x) + 2.

x_value = .014    #Offset by eye
y_value = .55

fig, ax = plt.subplots(1, 2, sharex = False, sharey = False)
fig.set_size_inches(50,30)

ax[0].plot(x, y, label = "cos")
ax[0].set_ylim([0.8,3.2])
ax[0].legend(loc=2)

line1 ,= ax[1].plot(x,y)
ax[1].set_ylim([0.8,3.2])

axbox = ax[1].get_position()

fig.legend([line1], ["cos"], loc = (axbox.x0 + x_value, axbox.y0 + y_value))

plt.show()

So what I am now doing is basically getting the coordinates from the subplot. I then create the legend based on the dimensions of the entire figure. Hence, the figure size does not change anything to the legend positioning anymore.

With the values for x_value and y_value the legend can be positioned in the subplot. x_value has been eyeballed for a good correspondence with the "normal" legend. This value can be changed at your desire. y_value determines the height of the legend.

Good luck!

Caleris

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]

or

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

Plot:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!