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

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


当前回答

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

在下面的示例中,我绘制了四行,在底部绘制了带有图例偏移的图像(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')

其他回答

只需在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和pylab的更新版本可以自动确定将图例放置在何处,而不干扰绘图。

pylab.legend(loc='best')

如果可能,这将自动将图例远离数据!

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

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

在下面的示例中,我绘制了四行,在底部绘制了带有图例偏移的图像(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')

简短回答:在图例上调用可拖动功能,并将其交互式移动到您想要的任何位置:

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

有很多方法可以做你想做的事。为了补充Christian Alis和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()

如果我们做同样的事情,但使用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图例指南。您还可以查看plt.figlegend()。