Python 在matplotlib plot下显示图例,并显示不同数量的绘图

Python 在matplotlib plot下显示图例,并显示不同数量的绘图,python,matplotlib,Python,Matplotlib,我正在开发一个程序,允许用户在轴上放置不同数量的绘图。我需要显示图例,并且绘图标签很长,所以我认为最好在绘图下显示。当我以前做过这件事时,我总是把情节缩小一点,把图例放在情节下面。现在有了不同数量的绘图,这就不那么简单了,因为我找不到一个好的公式来确定要缩小多少绘图,以及放置图例的深度,这样它就不会被切断或与轴重叠 我已经编写了一个示例代码来演示我目前正在做的事情,这很难看。我目前正在检查绘图中有多少项,并尝试手动优化轴收缩和图例偏移参数,然后执行大的if循环以使用手动优化的值。它们没有针对这个

我正在开发一个程序,允许用户在轴上放置不同数量的绘图。我需要显示图例,并且绘图标签很长,所以我认为最好在绘图下显示。当我以前做过这件事时,我总是把情节缩小一点,把图例放在情节下面。现在有了不同数量的绘图,这就不那么简单了,因为我找不到一个好的公式来确定要缩小多少绘图,以及放置图例的深度,这样它就不会被切断或与轴重叠

我已经编写了一个示例代码来演示我目前正在做的事情,这很难看。我目前正在检查绘图中有多少项,并尝试手动优化轴收缩和图例偏移参数,然后执行大的
if
循环以使用手动优化的值。它们没有针对这个示例代码进行优化,但我认为它演示了我正在做的事情

import matplotlib.pyplot as plt
import numpy as np

def find_scales(legendData):
        leg_len = len(legendData)
        if leg_len == 0:
            height_scale = 1
            legend_offset = 0
        elif leg_len == 1:
            height_scale = 0.96
            legend_offset = -0.18
        elif leg_len == 2:
            height_scale = 0.95
            legend_offset = -0.25
        elif leg_len == 3:
            height_scale = 0.94
            legend_offset = -0.35
        elif leg_len == 4:
            height_scale = 0.93
            legend_offset = -0.45
        elif leg_len == 5:
            height_scale = 0.93
            legend_offset = -0.57
        elif leg_len == 6:
            height_scale = 0.93
            legend_offset = -0.68
        elif leg_len == 7:
            height_scale = 0.93
            legend_offset = -0.82
        elif leg_len == 8:
            height_scale = 0.93
            legend_offset = -0.98
        elif leg_len == 9:
            height_scale = 0.92
            legend_offset = -1.3
        elif leg_len == 10:
            height_scale = 0.92
            legend_offset = -1.53
        else:
            height_scale = 0.92
            legend_offset = -1.8
        return height_scale, legend_offset

num_plots = 3
x_range = np.arange(10)

fig,ax = plt.subplots()

for i in range(num_plots):
    ax.plot(x_range, np.random.rand(10))

legend_labels = ['a','b','c','d','e','f','g','h','i','j'][:num_plots]

box = ax.get_position()

height_scale, legend_offset = find_scales(legend_labels)

ax.set_position([box.x0, box.y0 + box.height * (1-height_scale), #left, bottom, width, height
             box.width, box.height * height_scale])

ax.legend(legend_labels, loc=3, bbox_to_anchor=(0,legend_offset), borderaxespad=0.)

plt.show()

我希望有更好的办法。我希望图例位于轴下方。我不能让图例与轴或x标签重叠。我不能让图例因太低和超出图形而被切断。有没有办法使轴和图例自动调整大小以适合图形?

纠正轴位置的方法,以便图例有足够的空间,如此问题的答案所示:

对于位于底部的图例,解决方案要简单得多。基本上,您只需要从轴高度中减去图例高度,然后将轴向顶部移动图例高度

import matplotlib.pyplot as plt 

fig = plt.figure(figsize = [3.5,2]) 
ax = fig.add_subplot(111)
ax.set_title('title')
ax.set_ylabel('y label')
ax.set_xlabel('x label')
ax.plot([1,2,3], marker="o", label="quantity 1")
ax.plot([2,1.7,1.2], marker="s", label="quantity 2")

def legend(ax, x0=0.5,y0=0, pad=0.5,**kwargs):
    otrans = ax.figure.transFigure
    t = ax.legend(bbox_to_anchor=(x0,y0), loc=8, bbox_transform=otrans,**kwargs)
    ax.figure.tight_layout(pad=pad)
    ax.figure.canvas.draw()
    tbox = t.get_window_extent().transformed( ax.figure.transFigure.inverted() )
    bbox = ax.get_position()
    ax.set_position([bbox.x0, bbox.y0+tbox.height,bbox.width, bbox.height-tbox.height]) 

legend(ax,y0=0, borderaxespad=0.2)

plt.savefig(__file__+'.pdf')
plt.show()

您(几乎)是在线性缩放
高度比例
图例偏移量
作为
腿部长度的函数。因此,只需编写一个函数,为您计算它们,并抛弃所有的
if/elif
块。我猜这是您想要的答案(只是把图例放在绘图上方而不是下方)。可能重复@PaulH我花了时间试图找到一个缩放函数,但它似乎比线性缩放函数更复杂,这就是为什么我需要具体计算每个案例。@wwii这是我工作的岗位。它不解决图例中项目数量可变的问题。