我有一系列20幅图(不是子图)要在一个图中绘制。我希望图例在框外。同时,我不想改变轴,因为图形的大小会变小。

我希望图例框位于绘图区域之外(我希望图例位于绘图区域的右侧)。有没有办法减小图例框内文本的字体大小,使图例框的大小变小?


当前回答

只需在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))

结果如下:

其他回答

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

当你想写出来的时候,你可以提前将它们添加到图的艺术家中,而不是将所有添加添加到边界框中。使用类似于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")

.

这不完全是你所要求的,但我发现这是解决同样问题的一个替代方案。

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

使用以下工具执行此操作:

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)

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


更长的答案:您可以使用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_artists和bbox_inches要求savefig在保存的图像中包含裁剪的元素:

图savefig('image_output.png',bbox_extra_artits=(lgd,),bbox_inches='ight')

示例(我只更改了最后一行,在图savefig()中添加了2个参数):

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那样允许图例框的外部位置:

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])

只需在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))

结果如下:

如前所述,您也可以将图例放置在绘图中,或稍微偏离其边缘。下面是一个使用Plotly Python API的示例,该API是用IPython笔记本制作的。我是团队成员。

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

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移动图例和图形并重新设置其样式。要移动图例,可以使用以下选项通过指定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},文档中也有描述: