我绘制了相同类型的信息,但针对不同的国家,使用Matplotlib绘制了多个子图。也就是说,我在一个3x3网格上有9个图,所有的线都是相同的(当然,每条线的值不同)。

然而,我还没有弄清楚如何将一个图例(因为所有九个子图都有相同的线条)放在图形上一次。

我怎么做呢?


当前回答

使用Matplotlib 2.2.2,可以使用gridspec特性来实现这一点。

在下面的例子中,目标是以2x2的方式排列四个子情节,并在底部显示图例。在底部创建一个“人造”轴,将图例放置在固定的位置。“人造”轴然后关闭,所以只有传说显示。结果:

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

# Gridspec demo
fig = plt.figure()
fig.set_size_inches(8, 9)
fig.set_dpi(100)

rows   = 17 # The larger the number here, the smaller the spacing around the legend
start1 = 0
end1   = int((rows-1)/2)
start2 = end1
end2   = int(rows-1)

gspec = gridspec.GridSpec(ncols=4, nrows=rows)

axes = []
axes.append(fig.add_subplot(gspec[start1:end1, 0:2]))
axes.append(fig.add_subplot(gspec[start2:end2, 0:2]))
axes.append(fig.add_subplot(gspec[start1:end1, 2:4]))
axes.append(fig.add_subplot(gspec[start2:end2, 2:4]))
axes.append(fig.add_subplot(gspec[end2, 0:4]))

line, = axes[0].plot([0, 1], [0, 1], 'b')         # Add some data
axes[-1].legend((line,), ('Test',), loc='center') # Create legend on bottommost axis
axes[-1].set_axis_off()                           # Don't show the bottom-most axis

fig.tight_layout()
plt.show()

其他回答

还有一个很好的函数get_legend_handles_labels(),你可以在最后一个轴上调用(如果你迭代它们),它会收集你从label=参数中需要的一切:

handles, labels = ax.get_legend_handles_labels()
fig.legend(handles, labels, loc='upper center')

基于gboffi和Ben Usman的回答:

如果在不同的子图中有不同的线,但颜色和标签相同,你可以这样做:

labels_handles = {
  label: handle for ax in fig.axes for handle, label in zip(*ax.get_legend_handles_labels())
}

fig.legend(
  labels_handles.values(),
  labels_handles.keys(),
  loc = "upper center",
  bbox_to_anchor = (0.5, 0),
  bbox_transform = plt.gcf().transFigure,
)

所有之前的答案都超出了我的理解,在我的编码旅程的这个状态下,所以我只是添加了另一个Matplotlib方面,称为补丁:

import matplotlib.patches as mpatches

first_leg = mpatches.Patch(color='red', label='1st plot')
second_leg = mpatches.Patch(color='blue', label='2nd plot')
thrid_leg = mpatches.Patch(color='green', label='3rd plot')
plt.legend(handles=[first_leg ,second_leg ,thrid_leg ])

补丁方面把我需要的所有数据放在我的最终图(这是一个线状图,在Jupyter Notebook的同一个单元格中结合了三个不同的线状图)。

结果

(我更改了我自己命名的图例的名称。)

你只需要在循环之外请求一次图例。

例如,在这种情况下,我有4个子情节,具有相同的线,和一个图例。

from matplotlib.pyplot import *

ficheiros = ['120318.nc', '120319.nc', '120320.nc', '120321.nc']

fig = figure()
fig.suptitle('concentration profile analysis')

for a in range(len(ficheiros)):
    # dados is here defined
    level = dados.variables['level'][:]

    ax = fig.add_subplot(2,2,a+1)
    xticks(range(8), ['0h','3h','6h','9h','12h','15h','18h','21h']) 
    ax.set_xlabel('time (hours)')
    ax.set_ylabel('CONC ($\mu g. m^{-3}$)')

    for index in range(len(level)):
        conc = dados.variables['CONC'][4:12,index] * 1e9
        ax.plot(conc,label=str(level[index])+'m')

    dados.close()

ax.legend(bbox_to_anchor=(1.05, 0), loc='lower left', borderaxespad=0.)
         # it will place the legend on the outer right-hand side of the last axes

show()

Figlegend可能就是您要找的:matplotlib.pyplot.figlegend

一个例子是在图图例演示。

另一个例子:

plt.figlegend(lines, labels, loc = 'lower center', ncol=5, labelspacing=0.)

Or:

fig.legend(lines, labels, loc = (0.5, 0), ncol=5)