首页 文章

如何使用matplotlib为许多子图创建单个图例?

提问于
浏览
104

我正在绘制相同类型的信息,但对于不同的国家/地区,使用matplotlib的多个子图 . 也就是说,我在3x3网格上有9个图,所有线都相同(当然,每行不同的值) .

但是,我还没想出如何在图上只放一个图例(因为所有9个子图都有相同的线) .

我怎么做?

6 回答

  • 0

    figlegend可能是您要找的内容:http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.figlegend

    示例:http://matplotlib.org/examples/pylab_examples/figlegend_demo.html

    另一个例子:

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

    要么:

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

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

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

    你只需要在循环之外询问一次传奇 .

    例如,在这种情况下,我有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()
    
  • 15

    对于具有多个轴的 figure 中的单个图例的自动定位,如使用 subplots() 获得的那些,以下解决方案非常有效:

    plt.legend( lines, labels, loc = 'lower center', bbox_to_anchor = (0,-0.1,1,1),
                bbox_transform = plt.gcf().transFigure )
    

    使用 bbox_to_anchorbbox_transform=plt.gcf().transFigure ,您将定义 figure 大小的新边界框作为 loc 的引用 . 使用 (0,-0.1,1,1) 将此装饰框略微向下移动,以防止图例被放置在其他艺术家之上 .

    OBS:在使用 fig.set_size_inches() 之后使用此解决方案并在使用 fig.tight_layout() 之前

  • 13

    虽然比较晚了,但是我的假轴'然后关闭,所以只有传说显示 . 结果:https://i.stack.imgur.com/5LUWM.png .

    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 bottommost axis
    
    fig.tight_layout()
    plt.show()
    
  • 3

    这个答案是对@Evert's传奇位置的补充 .

    由于图例和子图 Headers 的重叠,我对@Evert的解决方案的第一次尝试失败了 .

    事实上,重叠是由 fig.tight_layout() 引起的,它改变了子图的布局而没有考虑图形图例 . 但是, fig.tight_layout() 是必要的 .

    为了避免重叠,我们可以通过 fig.tight_layout(rect=(0,0,1,0.9)) 告诉 fig.tight_layout() 为图形的图例留出空格 .

    Description of tight_layout() parameters .

相关问题