【问题标题】:How to put the legend outside the plot如何将图例置于情节之外
【发布时间】:2022-09-25 02:47:23
【问题描述】:

我有一系列 20 个图(不是子图)要在一个图中制作。我希望图例跳出框框。同时,我不想改变坐标轴,因为图形的尺寸变小了。

  1. 我想将图例框保留在绘图区域之外(我希望图例位于绘图区域右侧的外部)。
  2. 有没有办法减小图例框内文本的字体大小,从而使图例框的大小变小?

【问题讨论】:

标签: python matplotlib seaborn legend


【解决方案1】:

有很多方法可以做你想做的事。要添加到 what Christian AlisNavi already said,您可以使用 bbox_to_anchor 关键字参数将图例部分放置在轴外和/​​或减小字体大小。

在考虑减小字体大小(这会使内容非常难以阅读)之前,请尝试将图例放置在不同的位置:

那么,让我们从一个通用示例开始:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$' % i)

ax.legend()

plt.show()

如果我们做同样的事情,但使用 bbox_to_anchor 关键字参数,我们可以将图例稍微移动到轴边界之外:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$' % i)

ax.legend(bbox_to_anchor=(1.1, 1.05))

plt.show()

同样,使图例更水平和/或将其放在图的顶部(我也打开圆角和一个简单的投影):

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    line, = ax.plot(x, i * x, label='$y = %ix$'%i)

ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.05),
          ncol=3, fancybox=True, shadow=True)
plt.show()

或者,缩小当前绘图的宽度,并将图例完全放在图形轴之外(注意:如果您使用 tight_layout(),则省略 ax.set_position()

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$'%i)

# Shrink current axis by 20%
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])

# Put a legend to the right of the current axis
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))

plt.show()

并以类似的方式垂直缩小绘图,并在底部放置一个水平图例:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    line, = ax.plot(x, i * x, label='$y = %ix$'%i)

# Shrink current axis's height by 10% on the bottom
box = ax.get_position()
ax.set_position([box.x0, box.y0 + box.height * 0.1,
                 box.width, box.height * 0.9])

# Put a legend below current axis
ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),
          fancybox=True, shadow=True, ncol=5)

plt.show()

看看matplotlib legend guide。你也可以看看plt.figlegend()

【讨论】:

    【解决方案2】:

    放置图例 (bbox_to_anchor)

    使用 plt.legendloc 参数将图例定位在轴的边界框内。
    例如,loc="upper right" 将图例放在边界框的右上角,默认情况下,坐标轴坐标(或边界框符号 (x0, y0, width, height) = (0, 0, 1, 1))的范围从 (0, 0)(1, 1)

    要将图例放置在轴边界框之外,可以指定图例左下角轴坐标的元组(x0, y0)

    plt.legend(loc=(1.04, 0))
    

    一种更通用的方法是使用bbox_to_anchor争论。可以限制自己只提供 bbox 的 (x0, y0) 部分。这将创建一个零跨度框,图例将从该框向loc 参数指定的方向展开。例如。,

    plt.legend(bbox_to_anchor=(1.04, 1), loc="左上角")

    将图例放置在轴外,这样图例的左上角就位于轴坐标中的位置(1.04, 1)

    下面给出了更多示例,其中还显示了不同参数之间的相互作用,如 modencols

    l1 = plt.legend(bbox_to_anchor=(1.04, 1), borderaxespad=0)
    l2 = plt.legend(bbox_to_anchor=(1.04, 0), loc="lower left", borderaxespad=0)
    l3 = plt.legend(bbox_to_anchor=(1.04, 0.5), loc="center left", borderaxespad=0)
    l4 = plt.legend(bbox_to_anchor=(0, 1.02, 1, 0.2), loc="lower left",
                    mode="expand", borderaxespad=0, ncol=3)
    l5 = plt.legend(bbox_to_anchor=(1, 0), loc="lower right",
                    bbox_transform=fig.transFigure, ncol=3)
    l6 = plt.legend(bbox_to_anchor=(0.4, 0.8), loc="upper right")
    

    有关如何解释 bbox_to_anchor 的 4 元组参数的详细信息,如 l4 中所示,可以在 this question 中找到。 mode="expand" 在 4 元组给定的边界框内水平扩展图例。有关垂直展开的图例,请参阅this question

    有时在图形坐标而不是轴坐标中指定边界框可能很有用。这在上面的示例 l5 中显示,其中 bbox_transform 参数用于将图例放在图的左下角。

    后期处理

    将图例放置在坐标轴之外通常会导致出现完全或部分位于图形画布之外的不良情况。

    这个问题的解决方案是:

    • 调整子图参数
      可以通过使用plt.subplots_adjust 调整子图参数,使轴在图中占用更少的空间(从而为图例留出更多空间)。例如。,

      plt.subplots_adjust(right=0.7)
      

      在图的右侧留出 30% 的空间,可以放置图例。

    • 布局紧凑
      使用plt.tight_layout 允许自动调整子图参数,使图中的元素紧靠图形边缘。不幸的是,在这种自动化中没有考虑到图例,但我们可以提供一个矩形框,整个子图区域(包括标签)都可以放入其中。

      plt.tight_layout(rect=[0, 0, 0.75, 1])
      
    • bbox_inches = "tight"保存图形
      参数 bbox_inches = "tight"plt.savefig 可用于保存图形,使画布上的所有艺术家(包括图例)都适合保存的区域。如果需要,图形大小会自动调整。

      plt.savefig("output.png", bbox_inches="tight")
      
    • 自动调整子图参数
      一种自动调整子图位置以使图例适合画布的方法不改变图形大小可以在这个答案中找到:Creating figure with exact size and no padding (and legend outside the axes)

    上述案例的比较:

    备择方案

    人物传奇

    可以使用图例代替轴,matplotlib.figure.Figure.legend。这对于不需要特殊参数的 Matplotlib 2.1 版或更高版本特别有用

    fig.legend(loc=7)
    

    为人物不同轴上的所有艺术家创造一个传奇。图例使用 loc 参数放置,类似于它放置在轴内的方式,但参考整个图形 - 因此它会自动位于轴外。剩下的就是调整子图,使图例和轴之间没有重叠。重点在这里《调整子图参数》从上面会有所帮助。一个例子:

    import numpy as np
    import matplotlib.pyplot as plt
    
    x = np.linspace(0, 2*np.pi)
    colors = ["#7aa0c4", "#ca82e1", "#8bcd50", "#e18882"]
    fig, axes = plt.subplots(ncols=2)
    for i in range(4):
        axes[i//2].plot(x, np.sin(x+i), color=colors[i], label="y=sin(x + {})".format(i))
    
    fig.legend(loc=7)
    fig.tight_layout()
    fig.subplots_adjust(right=0.75)
    plt.show()
    

    专用子图轴内的图例

    使用 bbox_to_anchor 的替代方法是将图例放在其专用的子图轴 (lax) 中。 由于图例子图应该小于图,我们可以在轴创建时使用gridspec_kw={"width_ratios":[4, 1]}。 我们可以隐藏轴lax.axis("off"),但我们仍然放入图例。图例句柄和标签需要通过h, l = ax.get_legend_handles_labels()从真实图中获取,然后可以提供给lax子图中的图例,@987654380 @.下面是一个完整的例子。

    import matplotlib.pyplot as plt
    plt.rcParams["figure.figsize"] = 6, 2
    
    fig, (ax, lax) = plt.subplots(ncols=2, gridspec_kw={"width_ratios":[4, 1]})
    ax.plot(x, y, label="y=sin(x)")
    ....
    
    h, l = ax.get_legend_handles_labels()
    lax.legend(h, l, borderaxespad=0)
    lax.axis("off")
    
    plt.tight_layout()
    plt.show()
    

    这会产生一个视觉上与上面的图非常相似的图:

    我们也可以使用第一个轴来放置图例,但是使用图例轴的bbox_transform

    ax.legend(bbox_to_anchor=(0, 0, 1, 1), bbox_transform=lax.transAxes)
    lax.axis("off")
    

    在这种方法中,我们不需要从外部获取图例句柄,但我们需要指定bbox_to_anchor参数。

    进一步阅读和注意事项:

    • 考虑 Matplotlib legend guide 以及您想对图例进行的其他操作的一些示例。
    • 一些放置饼图图例的示例代码可以直接在这个问题的答案中找到:Python - Legend overlaps with the pie chart
    • loc 参数可以采用数字而不是字符串,这使得调用更短,但是,它们之间的映射不是很直观。这是供参考的映射:

    【讨论】:

      【解决方案3】:

      只需在 plot() 调用之后调用 legend(),如下所示:

      # Matplotlib
      plt.plot(...)
      plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))
      
      # Pandas
      df.myCol.plot().legend(loc='center left', bbox_to_anchor=(1, 0.5))
      

      结果看起来像这样:

      【讨论】:

      • 将相同的参数传递给 matplotlib.pyplot.legend 时也可以工作
      • 这是给别人截断了传说中的文字吗?
      • 调用“tight_layout()”为我修复了截断的单词。
      【解决方案4】:
      import matplotlib.pyplot as plt
      from matplotlib.font_manager import FontProperties
      
      fontP = FontProperties()
      fontP.set_size('xx-small')
      
      p1, = plt.plot([1, 2, 3], label='Line 1')
      p2, = plt.plot([3, 2, 1], label='Line 2')
      plt.legend(handles=[p1, p2], title='title', bbox_to_anchor=(1.05, 1), loc='upper left', prop=fontP)
      

      • fontsize='xx-small' 也可以,无需导入 FontProperties
      plt.legend(handles=[p1, p2], title='title', bbox_to_anchor=(1.05, 1), loc='upper left', fontsize='xx-small')
      

      【讨论】:

        【解决方案5】:

        要将图例放置在绘图区域之外,请使用legend()locbbox_to_anchor 关键字。例如,以下代码会将图例放置在绘图区域的右侧:

        legend(loc="upper left", bbox_to_anchor=(1,1))
        

        有关更多信息,请参阅legend guide

        【讨论】:

        • 好的 - 我喜欢这个实现,但是当我去保存图形时(没有在窗口中手动调整它的大小,我不想每次都这样做),图例被砍掉了。关于如何解决这个问题的任何想法?
        • @astromax 我不确定,但也许可以尝试致电plt.tight_layout()
        【解决方案6】:

        简短回答:您可以使用bbox_to_anchor + bbox_extra_artists + bbox_inches='tight'


        更长的答案: 正如其他人在答案中指出的那样,您可以使用 bbox_to_anchor 手动指定图例框的位置。

        但是,通常的问题是图例框被裁剪了,例如:

        import matplotlib.pyplot as plt
        
        # data 
        all_x = [10,20,30]
        all_y = [[1,3], [1.5,2.9],[3,2]]
        
        # Plot
        fig = plt.figure(1)
        ax = fig.add_subplot(111)
        ax.plot(all_x, all_y)
        
        # Add legend, title and axis labels
        lgd = ax.legend( [ 'Lag ' + str(lag) for lag in all_x], loc='center right', bbox_to_anchor=(1.3, 0.5))
        ax.set_title('Title')
        ax.set_xlabel('x label')
        ax.set_ylabel('y label')
        
        fig.savefig('image_output.png', dpi=300, format='png')
        

        为了防止图例框被裁剪,保存图形时可以使用参数bbox_extra_artistsbbox_inches要求savefig在保存的图像中包含裁剪元素:

        fig.savefig('image_output.png', bbox_extra_artists=(lgd,), bbox_inches='tight')

        示例(我只更改了最后一行以将 2 个参数添加到 fig.savefig()):

        import matplotlib.pyplot as plt
        
        # data 
        all_x = [10,20,30]
        all_y = [[1,3], [1.5,2.9],[3,2]]
        
        # Plot
        fig = plt.figure(1)
        ax = fig.add_subplot(111)
        ax.plot(all_x, all_y)
        
        # Add legend, title and axis labels
        lgd = ax.legend( [ 'Lag ' + str(lag) for lag in all_x], loc='center right', bbox_to_anchor=(1.3, 0.5))
        ax.set_title('Title')
        ax.set_xlabel('x label')
        ax.set_ylabel('y label')    
        
        fig.savefig('image_output.png', dpi=300, format='png', bbox_extra_artists=(lgd,), bbox_inches='tight')
        

        我希望 matplotlib 本身允许图例框的外部位置为 Matlab does

        figure
        x = 0:.2:12;
        plot(x,besselj(1,x),x,besselj(2,x),x,besselj(3,x));
        hleg = legend('First','Second','Third',...
                      'Location','NorthEastOutside')
        % Make the text of the legend italic and color it brown
        set(hleg,'FontAngle','italic','TextColor',[.3,.2,.1])
        

        【讨论】:

        • 谢谢,但实际上 bbox_inches='tight' 即使没有 bbox_extra_artist 也能完美地工作
        • @avtomaton 谢谢,很高兴知道,您使用哪个版本的 matplotlib?
        • @FranckDernoncourt python3,matplotlib 版本 1.5.3
        【解决方案7】:

        除了这里的所有优秀答案之外,更新版本的matplotlibpylab可以在不干扰绘图的情况下自动确定放置图例的位置, 如果可能的话。

        pylab.legend(loc='best')
        

        如果可能的话,这会自动将图例放置在远离数据的位置!

        但是,如果没有任何地方可以在不重叠数据的情况下放置图例,那么您将需要尝试其他答案之一;使用loc="best" 永远不会放图例外部的情节。

        【讨论】:

        • 感谢您指出这一点!几年前我找过这个但没有找到,它确实让我的生活更轻松。
        • 这个选项很有用,但没有回答问题,所以我投了反对票。据我所知,最好永远不要把传说放在情节之外
        • @Tommy:在 OP 的 cmets(现在似乎已经消失)中明确阐明了 OP 希望图例不覆盖图形数据,他认为在情节之外是唯一的方法。您可以在 Mefathy、Mateo Sanchez、Bastiaan 和 radtek 的回答中看到这一点。 OP asked for X, but he wanted Y
        • 其实并不是。他/她特别要求图例在情节之外。这是问题的名称;)“如何将传说从情节中剔除”。
        • 这并不能保证图例不会遮盖数据。只是做一个非常密集的情节——没有地方放传说。例如,试试这个... from numpy import arange, sin, pi import matplotlib.pyplot as plt t = arange(0.0, 100.0, 0.01) fig = plt.figure(1) ax1 = fig.add_subplot(211) ax1。 scatter(t, sin(2*pi*t),label='test') ax1.grid(True) # ax1.set_ylim((-2, 2)) ax1.set_ylabel('1 Hz') ax1.set_title( '一个或两个正弦波')用于 ax1.get_xticklabels() 中的标签:label.set_color('r') plt.legend(loc='best') plt.show()
        【解决方案8】:

        简答:在图例上调用 draggable 并以交互方式将其移动到您想要的任何位置:

        ax.legend().draggable()
        

        长答案:如果您更喜欢以交互方式/手动方式而不是以编程方式放置图例,则可以切换图例的可拖动模式,以便可以将其拖动到您想要的任何位置。检查下面的例子:

        import matplotlib.pylab as plt
        import numpy as np
        #define the figure and get an axes instance
        fig = plt.figure()
        ax = fig.add_subplot(111)
        #plot the data
        x = np.arange(-5, 6)
        ax.plot(x, x*x, label='y = x^2')
        ax.plot(x, x*x*x, label='y = x^3')
        ax.legend().draggable()
        plt.show()
        

        【讨论】:

        • 不确定我是否完全理解这一点。我如何将图例“拖”到我想要的任何地方?我正在使用 Python 3.6 和 Jupyter Notebook
        【解决方案9】:

        较新版本的 Matplotlib 使得将图例定位在绘图之外变得更加容易。我用 Matplotlib 版本 3.1.1 制作了这个例子。

        用户可以将 2 元组坐标传递给 loc 参数,以将图例定位在边界框中的任意位置。唯一的问题是您需要运行plt.tight_layout() 来让 matplotlib 重新计算绘图尺寸,以便图例可见:

        import matplotlib.pyplot as plt
        
        plt.plot([0, 1], [0, 1], label="Label 1")
        plt.plot([0, 1], [0, 2], label='Label 2')
        
        plt.legend(loc=(1.05, 0.5))
        plt.tight_layout()
        

        这导致以下情节:

        参考:

        【讨论】:

          【解决方案10】:

          这不完全是您要求的,但我发现它是解决同一问题的替代方法。

          使图例半透明,如下所示:

          这样做:

          fig = pylab.figure()
          ax = fig.add_subplot(111)
          ax.plot(x, y, label=label, color=color)
          # Make the legend transparent:
          ax.legend(loc=2, fontsize=10, fancybox=True).get_frame().set_alpha(0.5)
          # Make a transparent text box
          ax.text(0.02, 0.02, yourstring, verticalalignment='bottom',
                              horizontalalignment='left',
                              fontsize=10,
                              bbox={'facecolor':'white', 'alpha':0.6, 'pad':10},
                              transform=self.ax.transAxes)
          

          【讨论】:

            【解决方案11】:

            如前所述,您还可以将图例放置在绘图中,或者稍微偏离它的边缘。这是一个使用 Plotly Python API 的示例,由 IPython Notebook 制作。我在队里。

            首先,您需要安装必要的软件包:

            import plotly
            import math
            import random
            import numpy as np
            

            然后,安装 Plotly:

            un='IPython.Demo'
            k='1fw3zw2o13'
            py = plotly.plotly(username=un, key=k)
            
            
            def sin(x,n):
            sine = 0
            for i in range(n):
                sign = (-1)**i
                sine = sine + ((x**(2.0*i+1))/math.factorial(2*i+1))*sign
            return sine
            
            x = np.arange(-12,12,0.1)
            
            anno = {
            'text': '$\sum_{k=0}^{\infty} \frac {(-1)^k x^{1+2k}}{(1 + 2k)!}$',
            'x': 0.3, 'y': 0.6,'xref': "paper", 'yref': "paper",'showarrow': False,
            'font':{'size':24}
            }
            
            l = {
            'annotations': [anno], 
            'title': 'Taylor series of sine',
            'xaxis':{'ticks':'','linecolor':'white','showgrid':False,'zeroline':False},
            'yaxis':{'ticks':'','linecolor':'white','showgrid':False,'zeroline':False},
            'legend':{'font':{'size':16},'bordercolor':'white','bgcolor':'#fcfcfc'}
            }
            
            py.iplot([{'x':x, 'y':sin(x,1), 'line':{'color':'#e377c2'}, 'name':'$x\\$'},
                  {'x':x, 'y':sin(x,2), 'line':{'color':'#7f7f7f'},'name':'$ x-\frac{x^3}{6}$'},
                  {'x':x, 'y':sin(x,3), 'line':{'color':'#bcbd22'},'name':'$ x-\frac{x^3}{6}+\frac{x^5}{120}$'},
                  {'x':x, 'y':sin(x,4), 'line':{'color':'#17becf'},'name':'$ x-\frac{x^5}{120}$'}], layout=l)
            

            这将创建您的图表,并让您有机会将图例保留在图表本身中。如果未设置图例,则默认将其放置在绘图中,如此处所示。

            对于替代放置,您可以紧密对齐图形的边缘和图例的边框,并移除边框线以获得更紧密的贴合。

            您可以使用代码或 GUI 移动和重新设置图例和图形的样式。要移动图例,您可以使用以下选项通过分配 <= 1 的 x 和 y 值来将图例定位在图表中。例如:

            • {"x" : 0,"y" : 0} -- 左下角
            • {"x" : 1, "y" : 0} -- 右下角
            • {"x" : 1, "y" : 1} -- 右上角
            • {"x" : 0, "y" : 1} -- 左上角
            • {"x" :.5, "y" : 0} -- 底部居中
            • {"x": .5, "y" : 1} -- 顶中心

            本例我们选择右上角,legendstyle = {"x" : 1, "y" : 1},在the documentation中也有说明:

            【讨论】:

              【解决方案12】:

              我只是使用字符串 'center left' 作为位置,例如 MATLAB

              我从 Matplotlib 导入了 pylab。

              看代码如下:

              from matplotlib as plt
              from matplotlib.font_manager import FontProperties
              
              t = A[:, 0]
              sensors = A[:, index_lst]
              
              for i in range(sensors.shape[1]):
                  plt.plot(t, sensors[:, i])
              
              plt.xlabel('s')
              plt.ylabel('°C')
              lgd = plt.legend(loc='center left', bbox_to_anchor=(1, 0.5), fancybox = True, shadow = True)
              

              【讨论】:

                【解决方案13】:

                你也可以试试figlegend。可以创建独立于任何 Axes 对象的图例。但是,您可能需要创建一些“虚拟”路径以确保正确传递对象的格式。

                【讨论】:

                  【解决方案14】:

                  这些方面的一些东西对我有用。从 Joe 的一些代码开始,此方法修改窗口宽度以自动将图例适合图的右侧。

                  import matplotlib.pyplot as plt
                  import numpy as np
                  
                  plt.ion()
                  
                  x = np.arange(10)
                  
                  fig = plt.figure()
                  ax = plt.subplot(111)
                  
                  for i in xrange(5):
                      ax.plot(x, i * x, label='$y = %ix$'%i)
                  
                  # Put a legend to the right of the current axis
                  leg = ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
                  
                  plt.draw()
                  
                  # Get the ax dimensions.
                  box = ax.get_position()
                  xlocs = (box.x0,box.x1)
                  ylocs = (box.y0,box.y1)
                  
                  # Get the figure size in inches and the dpi.
                  w, h = fig.get_size_inches()
                  dpi = fig.get_dpi()
                  
                  # Get the legend size, calculate new window width and change the figure size.
                  legWidth = leg.get_window_extent().width
                  winWidthNew = w*dpi+legWidth
                  fig.set_size_inches(winWidthNew/dpi,h)
                  
                  # Adjust the window size to fit the figure.
                  mgr = plt.get_current_fig_manager()
                  mgr.window.wm_geometry("%ix%i"%(winWidthNew,mgr.window.winfo_height()))
                  
                  # Rescale the ax to keep its original size.
                  factor = w*dpi/winWidthNew
                  x0 = xlocs[0]*factor
                  x1 = xlocs[1]*factor
                  width = box.width*factor
                  ax.set_position([x0,ylocs[0],x1-x0,ylocs[1]-ylocs[0]])
                  
                  plt.draw()
                  

                  【讨论】:

                  • 我发现这非常有用并且对我有用。请注意,如果您在 wx 后端(例如使用 Windows),请将 mgr.window.wm_geometry("%ix%i"%(winWidthNew,mgr.window.winfo_height())) 替换为 mgr.window.SetClientSizeWH(winWidthNew ,winHeightNew) 之类的
                  • 如果您使用的是 Qt4Agg 后端(这是我在 Linux 安装的 matplotlib 上的默认设置),请将 mgr.window.wm_geometry(...) 行替换为 mgr.window.setFixedWidth(winWidthNew)
                  • 而且,正如我刚刚发现的那样,如果您使用的后端不显示任何窗口,即用于直接保存到文件(如 SVG 和 AGG 后端),则完全跳过窗口大小调整。 fig.set_size_inches(...) 负责您需要的调整大小。
                  【解决方案15】:

                  当我有一个巨大的图例时,对我有用的解决方案是使用额外的空图像布局。

                  在下面的示例中,我制作了四行,并在底部绘制了带有图例偏​​移量的图像 (bbox_to_anchor)。在顶部,它不会被切割。

                  f = plt.figure()
                  ax = f.add_subplot(414)
                  lgd = ax.legend(loc='upper left', bbox_to_anchor=(0, 4), mode="expand", borderaxespad=0.3)
                  ax.autoscale_view()
                  plt.savefig(fig_name, format='svg', dpi=1200, bbox_extra_artists=(lgd,), bbox_inches='tight')
                  

                  【讨论】:

                    【解决方案16】:

                    这是另一个解决方案,类似于添加 bbox_extra_artistsbbox_inches,您不必在 savefig 调用范围内拥有额外的艺术家。我想出了这个,因为我在函数内部生成了大部分情节。

                    您可以提前将它们添加到 Figure 的艺术家,而不是在您想要将其写出时将所有添加添加到边界框。使用类似于 Franck Dernoncourt's answer 的内容:

                    import matplotlib.pyplot as plt
                    
                    # Data
                    all_x = [10, 20, 30]
                    all_y = [[1, 3], [1.5, 2.9], [3, 2]]
                    
                    # Plotting function
                    def gen_plot(x, y):
                        fig = plt.figure(1)
                        ax = fig.add_subplot(111)
                        ax.plot(all_x, all_y)
                        lgd = ax.legend(["Lag " + str(lag) for lag in all_x], loc="center right", bbox_to_anchor=(1.3, 0.5))
                        fig.artists.append(lgd) # Here's the change
                        ax.set_title("Title")
                        ax.set_xlabel("x label")
                        ax.set_ylabel("y label")
                        return fig
                    
                    # Plotting
                    fig = gen_plot(all_x, all_y)
                    
                    # No need for `bbox_extra_artists`
                    fig.savefig("image_output.png", dpi=300, format="png", bbox_inches="tight")
                    

                    【讨论】:

                      【解决方案17】:

                      这是来自 here 的 matplotlib 教程中的示例。这是更简单的示例之一,但我为图例添加了透明度并添加了 plt.show() 以便您可以将其粘贴到交互式 shell 中并获得结果:

                      import matplotlib.pyplot as plt
                      p1, = plt.plot([1, 2, 3])
                      p2, = plt.plot([3, 2, 1])
                      p3, = plt.plot([2, 3, 1])
                      plt.legend([p2, p1, p3], ["line 1", "line 2", "line 3"]).get_frame().set_alpha(0.5)
                      plt.show()
                      

                      【讨论】:

                        猜你喜欢
                        • 2020-02-28
                        • 1970-01-01
                        • 1970-01-01
                        • 2021-12-09
                        • 2019-09-30
                        • 2021-03-17
                        • 1970-01-01
                        • 2021-02-15
                        • 2020-05-19
                        相关资源
                        最近更新 更多