代码之家  ›  专栏  ›  技术社区  ›  Cebbie

使用两个轴打印时,如何填充图例背景色?

  •  4
  • Cebbie  · 技术社区  · 8 年前

    问题

    我有一个有两个y轴的图,每个y轴对应一组线。实线对应于左y轴,虚线对应于右y轴。我也有一个传说,我只想用它 实线

    问题是当我为实线绘制图例,然后为虚线绘制代码时,网格线通过图例显示。我需要为两个轴指定网格线,因为它们不会以其他方式显示,如果我将图例移动到虚线,它将使用虚线作为关键点。我也不想改变我的绘图顺序。

    代码和绘图

    #Plot
    x= np.arange(0,3)
    fig,ax = plt.subplots(figsize=(6,6))
    #DOD
    dod1 = ax.plot(x, ctrl_dod,  color='r',       label='CTRL'  )
    dod2 = ax.plot(x, mfkc_dod,  color='#e68a00', label='MFKC'  )
    dod3 = ax.plot(x, gses_dod,  color='green',   label='GSES'  )
    dod4 = ax.plot(x, gses3_dod, color='blue',    label='GSES-3')
    dod5 = ax.plot(x, gses4_dod, color='purple',  label='GSES-4')
    dod6 = ax.plot(x, mera_dod,  color='brown',   label='MERRA2')
    ax.xaxis.grid(True)
    ax.set_ylim([0.02,0.044])
    ax.set_yticks(np.arange(0.02,0.045,0.004))
    ax.set_xlabel('Month')
    ax.set_ylabel('Dust Optical Depth (550 nm)')
    ax.set_title('Global Mean DOD and DCM')
    legend = ax.legend()
    legend.get_frame().set_facecolor('white')
    
    #DCM
    ax2  = ax.twinx()
    dcm1 = ax2.plot(x, ctrl_dcm*1e6,  color='r',       linestyle='--', label='CTRL'  )
    dcm2 = ax2.plot(x, mfkc_dcm*1e6,  color='#e68a00', linestyle='--', label='MFKC'  )
    dcm3 = ax2.plot(x, gses_dcm*1e6,  color='green',   linestyle='--', label='GSES'  )
    dcm4 = ax2.plot(x, gses3_dcm*1e6, color='blue',    linestyle='--', label='GSES-3')
    dcm5 = ax2.plot(x, gses4_dcm*1e6, color='purple',  linestyle='--', label='GSES-4')
    dcm6 = ax2.plot(x, mera_dcm*1e6,  color='brown',   linestyle='--', label='MERRA2')
    ax2.xaxis.grid(True)
    ax2.yaxis.grid(True)
    ax2.set_xlabel('Month')
    ax2.set_ylabel('Dust Column Mass (mg m-2)')
    
    #Limits
    axes = plt.gca()
    axes.set_xlim([-0.25,2.25])
    
    #Labels
    axes.set_xticks(x)
    axes.set_xticklabels(['June','July','August'])
    
    #Save
    pylab.savefig('dod+dcm.png')
    

    enter image description here

    我怎么能

    b) 图例的背景是白色的吗?

    2 回复  |  直到 8 年前
        1
  •  5
  •   ImportanceOfBeingErnest    8 年前

    您可以为第二个轴创建图例,但使用第一个轴的控制柄。

    h, l = ax.get_legend_handles_labels()
    legend = ax2.legend(h,l, facecolor="white")
    
        2
  •  0
  •   Bastian    4 年前

    我来到这里,因为我有同样的问题,但想要两个独立的传说,每一个双轴一个。

    @ImportanceOfBeingErnest提供的公认答案不再有效,因为它只允许将一个图例附加到 ax2

    https://github.com/matplotlib/matplotlib/issues/3706#issuecomment-378407795 .

    我将它们都转换为一个函数,我通常在本例中使用这个函数,并认为在这里提供它会很有用:

    def legend_to_ax( ax, ax_placein=None, method=2, **kwargs ):
        """ Wrapper around ax.legend(**kwargs) which permits to have the legend
        placed in the axis ax_placein.
        This is useful when drawing legends for multiple axes, e.g.produced with
        ax2 = ax1.twinx(), in order to have all legends on top of all axes.
        In this case provide the uppermost axis, e.g. ax2 here, as ax_placein.
        Args:
         - ax         : axis for which the legend is created
         - ax_placein : axis which the legend should be placed in (optional)
         - method     : method by which to handle the placement of the legend in
                        ax_placein.
                        method=1 ... based on 
                                     https://stackoverflow.com/a/45336414/7042795
                                     This method fails when multiple legends should
                                     be added to ax_placein.
                        method=2 ... based on
                                     https://github.com/matplotlib/matplotlib/issues/3706#issuecomment-378407795
                                     This adds the legend as an artist to ax_placein
                                     making it no longer appear via ax.get_legend().
                                     Instead parse ax_placein.artists()
         - **kwargs   : kwargs of ax.legend()
        Returns:
         - leg        : legend handle
        """
    
        if ax_placein is None:
            leg = ax.legend(**kwargs)
        
        elif method==1:
            # based on https://stackoverflow.com/a/45336414/7042795
            h, l = ax.get_legend_handles_labels()
            if ax_placein is not None:
                ax = ax_placein
            leg =  ax.legend( h, l, **kwargs)
        
        elif method==2:
            # based on https://github.com/matplotlib/matplotlib/issues/3706#issuecomment-378407795
            leg = ax.legend(**kwargs)
            if ax_placein is not None:
                leg.remove()
                ax_placein.add_artist(leg)
        
        return leg
    

    因此,使用此函数,您可以简单地执行以下操作

    legend = legend_to_ax( ax, ax_placein=ax2, method=1, facecolor="white")
    

    legend = legend_to_ax( ax, ax_placein=ax2, method=2, facecolor="white")
    

    legend1 = legend_to_ax( ax,  ax_placein=ax2, method=2, facecolor="white", loc="upper left")
    legend2 = legend_to_ax( ax2, ax_placein=ax2, method=2, facecolor="white", loc="upper right")