如何将传说从情节中删除

pot*_*opi 866 python matplotlib legend

我有一系列20个图(不是子图)可以在一个图中制作.我希望传说能够在盒子之外.同时,我不想改变轴,因为图形的大小减少了.请帮助我以下查询:

  1. 我想将情节框保留在情节区域之外.(我希望传说位于情节区域的右侧).
  2. 无论如何,我减少了图例框内文本的字体大小,因此图例框的大小会很小.

Joe*_*ton 1633

有很多方法可以做你想做的事.要添加@inalis和@Navi已经说过的内容,可以使用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()
Run Code Online (Sandbox Code Playgroud)

替代文字

如果我们做同样的事情,但使用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()
Run Code Online (Sandbox Code Playgroud)

替代文字

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

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()
Run Code Online (Sandbox Code Playgroud)

替代文字

或者,您可以缩小当前图的宽度,并将图例完全放在图的轴外:

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()
Run Code Online (Sandbox Code Playgroud)

替代文字

以类似的方式,您可以垂直缩小绘图,并将水平图例放在底部:

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()
Run Code Online (Sandbox Code Playgroud)

替代文字

看看matplotlib图例指南.你也可以看看plt.figlegend().无论如何,希望有所帮助!

  • 请注意,如果要将图形保存到文件中,则应该存储返回的对象,即`legend = ax.legend()`以及稍后`fig.savefig(bbox_extra_artists =(legend,))` (8认同)
  • 如果有人遇到此问题,请注意tight_layout()会导致问题! (7认同)
  • 很好的答案!与文档的正确链接是http://matplotlib.org/users/legend_guide.html#legend-location (4认同)
  • 我必须承认,这可能是我访问量最大的SO答案.我无法一次又一次地回到它身边,因为没有合理的人能够记住这个逻辑而不在这里查找它. (4认同)
  • 作为完整性,你可以说一般(从文档中总结)"`bbox_to_anchor`是4个浮点数的元组(x,y,宽度,bbox的高度),或2个浮点数的元组(x,y)在归一化轴坐标中." (3认同)

Imp*_*est 657

放置图例(bbox_to_anchor)

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

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

plt.legend(loc=(1.04,0))
Run Code Online (Sandbox Code Playgroud)

但是,更通用的方法是使用bbox_to_anchor参数手动指定应放置图例的边界框.人们可以限制自己只提供(x0,y0)bbox 的一部分.这将创建一个零跨度框,其中图例将按loc参数给定的方向展开.例如

__PRE__

将图例放在轴外,使图例的左上角(1.04,1)位于轴坐标的位置.

另外的例子在下面给出,其中另外不同的参数之间的相互作用等modencols被示出.

在此输入图像描述

plt.legend(bbox_to_anchor=(1.04,1), loc="upper left")

要如何解释4元组参数的详细信息bbox_to_anchor,如l4,可以在发现这个问题.的mode="expand"由4元组给出的边界框内水平方向扩展的图例.对于垂直展开的图例,请参阅此问题.

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

后期处理

将图例放置在轴外部通常会导致不希望的情况,即它完全或部分位于图形画布之外.

这个问题的解决方案是:

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

    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")
    
    Run Code Online (Sandbox Code Playgroud)

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

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

    plt.subplots_adjust(right=0.7)
    
    Run Code Online (Sandbox Code Playgroud)
  • 保存图形bbox_inches = "tight"可以使用
    参数bbox_inches = "tight"plt.savefig保存图形,使画布上的所有艺术家(包括图例)都适合保存的区域.如果需要,可自动调整图形大小.

    plt.tight_layout(rect=[0,0,0.75,1])
    
    Run Code Online (Sandbox Code Playgroud)
  • 自动调整子
    画面参数自动调整子画面位置的方法,使得图例适合画布而不改变图形大小可以在这个答案中找到:创建具有精确尺寸且没有填充的图形(以及轴外的图例)

上述案例之间的比较:

在此输入图像描述

备择方案

图形图例
可以使用图形而不是轴的图例matplotlib.figure.Figure.legend.这对于matplotlib版本> = 2.1特别有用,它不需要特殊的参数

plt.savefig("output.png", bbox_inches="tight")
Run Code Online (Sandbox Code Playgroud)

为图中不同轴的所有艺术家创建一个图例.使用loc参数放置图例,类似于它放置在轴内的方式,但是参考整个图形 - 因此它会稍微自动地在轴外.剩下的就是调整子图,使图例和轴之间没有重叠. 从上面的"调整子图​​参数"这一点将会很有帮助.一个例子:

fig.legend(loc=7) 
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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

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()
Run Code Online (Sandbox Code Playgroud)

这会产生一个视觉上非常类似于上图的情节:

在此输入图像描述

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

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()
Run Code Online (Sandbox Code Playgroud)

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

进一步阅读和说明:

  • 考虑一下matplotlib 图例指南,以及一些你想用传说做的其他东西的例子.
  • 在回答这个问题时可以直接找到一些用于为饼图放置图例的示例代码:Python - Legend与饼图重叠
  • loc参数可以使用数字,而不是字符串,使通话更短,但是,他们不是很直观地映射到对方.以下是参考的映射:

在此输入图像描述

  • 也许你可以将它贡献给matplotlib文档? (35认同)
  • 这是我读过的最全面、内容最丰富、写得最好的 StackOverflow 帖子之一。这回答了我的每一个问题,甚至更多。太感谢了! (11认同)

Shi*_*hah 148

只需在通话legend()plot()拨打电话,如下所示:

# 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))
Run Code Online (Sandbox Code Playgroud)

结果看起来像这样:

在此输入图像描述

  • 将相同的参数传递给matplotlib.pyplot.legend时也能正常工作 (4认同)
  • 这会切断别人的传说中的文字吗? (2认同)

Nav*_*avi 87

创建字体属性

from matplotlib.font_manager import FontProperties

fontP = FontProperties()
fontP.set_size('small')
legend([plot1], "title", prop=fontP) 
# or add prop=fontP to whatever legend() call you already have
Run Code Online (Sandbox Code Playgroud)

  • 这个答案中的`plot1`是什么? (38认同)
  • 在这个答案中什么是"传奇"? (29认同)
  • 这个答案很糟糕,提供的背景很少! (18认同)
  • 这回答了问题的次要部分,但不是主要的(标题为). (12认同)
  • 另外,正确的方法是`plt.legend(fontsize ='small')`。 (7认同)
  • 关于您要回答的问题以及代码中发生的事情的一些解释会很好。从Google进来时,这非常令人困惑 (2认同)

Fra*_*urt 77

简短的回答:你可以使用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')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

为了防止图例框被裁剪,当您保存图形时,您可以使用参数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')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我希望matplotlib本身允许传说框的外部位置,如Matlab所做的那样:

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])
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 非常感谢!"bbox_to_anchor","bbox_extra_artist"和""bbox_inches ='tight"参数正是我所需要的,使其正常工作.太棒了! (6认同)
  • 谢谢你,但实际上`bbox_inches ='tight''对我来说非常适合,即使没有bbox_extra_artist (4认同)

Chr*_*lis 71

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

legend(loc="upper left", bbox_to_anchor=(1,1))
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅图例指南

  • 好的 - 我喜欢这个实现,但是当我去保存图形时(没有在窗口中手动调整它,我不想每次都这样做),传说就会被切断.关于我如何解决这个问题的任何想法? (8认同)
  • @astromax 我不确定,但也许尝试调用 `plt.tight_layout()`? (2认同)

dot*_*hen 61

除了这里所有优秀的答案之外,更新的版本matplotlibpylab可以自动确定放置图例的位置而不会干扰图表.

pylab.legend(loc='best')
Run Code Online (Sandbox Code Playgroud)

这将自动将图例放在图表之外! 比较loc ='best'的用法

  • 这个选项很有帮助,但没有回答这个问题,所以我downvoted.据我所知,最好永远不要把传说放在情节之外 (4认同)
  • 这并不能保证图例不会遮挡数据.只是做一个非常密集的情节 - 没有地方可以把传说.例如,试试这个...从numpy import arange,sin,pi import matplotlib.pyplot作为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() (4认同)
  • @Tommy:在OP的评论中(现在似乎已经消失),明确澄清了OP希望图例不能覆盖图表数据,他认为在情节之外是唯一的方法.你可以在mefathy,Mateo Sanchez,Bastiaan和radtek的答案中看到这一点.OP [要求X,但他想要Y](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). (3认同)
  • 感谢您指出这一点!几年前我找过这个,但没有找到,它确实让我的生活更轻松。 (2认同)

mef*_*thy 55

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

ax.legend().draggable()
Run Code Online (Sandbox Code Playgroud)

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

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()
Run Code Online (Sandbox Code Playgroud)


tdy*_*tdy 25

matplotlib 3.7 中的新增功能

图例现在直接接受“外部”位置,例如loc='outside right upper'

只需确保布局受到约束,然后在loc字符串前面添加“outside”:

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(layout='constrained')
#                      --------------------

x = np.linspace(-np.pi, np.pi)
ax.plot(x, x, label='$f(x) = x$')
ax.plot(x, np.sin(x), label='$f(x) = sin(x)$')
ax.plot(x, np.cos(x), label='$f(x) = cos(x)$')

fig.legend(loc='outside right upper')
#               -------

plt.show()
Run Code Online (Sandbox Code Playgroud)

多个子图也适用于新的“外部”位置:

fig, (ax1, ax2) = plt.subplots(1, 2, layout='constrained')
#                                    --------------------

x = np.linspace(-np.pi, np.pi)
ax1.plot(x, x,         '-',  label='$f(x) = x$')
ax1.plot(x, np.sin(x), '--', label='$f(x) = sin(x)$')
ax2.plot(x, np.cos(x), ':',  label='$f(x) = cos(x)$')

fig.legend(loc='outside right center')
#               -------
Run Code Online (Sandbox Code Playgroud)

当然,可用的“外部”位置是预设的,因此如果您需要更精细的定位,请使用旧的答案。然而,标准位置应该适合大多数用例:

locs = [
    'outside upper left', 'outside upper center', 'outside upper right',
    'outside center right', 'upper center left',
    'outside lower right', 'outside lower center', 'outside lower left',
]
for loc in locs:
    fig.legend(loc=loc, title=loc)
Run Code Online (Sandbox Code Playgroud)

locs = [
    'outside right upper', 'outside right lower',
    'outside left lower', 'outside left upper',
]
for loc in locs:
    fig.legend(loc=loc, title=loc)
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是不适用于 ax (例如 `ax.legend(loc="outside lower left", ncols=3)`)。 (2认同)

Bas*_*aan 13

不完全是你要求的,但我发现它是同一问题的替代方案.让传奇半透明,如下: 带有半透明图例和半透明文本框的matplotlib图

这样做:

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)
Run Code Online (Sandbox Code Playgroud)


小智 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()
Run Code Online (Sandbox Code Playgroud)

这导致了以下情节:

外面有图例的情节

参考:


小智 8

我只是使用字符串'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)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


Mat*_*hez 7

如上所述,您还可以将图例放置在绘图中,或稍微偏离边缘.下面是使用Plotly Python API的示例,该APIIPython Notebook完成.我在团队中.

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

import plotly
import math
import random
import numpy as np
Run Code Online (Sandbox Code Playgroud)

然后,安装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)
Run Code Online (Sandbox Code Playgroud)

这将创建您的图形,并允许您有机会将图例保留在图表本身中.如果未设置,则图例的默认值是将其放置在图中,如此处所示.

在此输入图像描述

对于替代放置,您可以紧密对齐图形的边缘和图例的边框,并删除边框线以便更贴合.

在此输入图像描述

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

  • {"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},也在文档中描述:

在此输入图像描述


Uri*_*son 5

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


ivi*_*hup 5

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

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

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")
Run Code Online (Sandbox Code Playgroud)

这是生成的图