Python 如何将图例排除在情节之外

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4700614/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 17:02:39  来源:igfitidea点击:

How to put the legend out of the plot

pythonmatplotliblegend

提问by pottigopi

I have a series of 20 plots (not subplots) to be made in a single figure. I want the legend to be outside of the box. At the same time, I do not want to change the axes, as the size of the figure gets reduced. Kindly help me for the following queries:

我在一个图中制作了一系列 20 个图(不是子图)。我希望图例在框外。同时,我不想改变轴,因为图形的大小变小了。请帮助我解决以下问题:

  1. I want to keep the legend box outside the plot area. (I want the legend to be outside at the right side of the plot area).
  2. Is there anyway that I reduce the font size of the text inside the legend box, so that the size of the legend box will be small.
  1. 我想将图例框保留在绘图区域之外。(我希望图例位于情节区域的右侧)。
  2. 无论如何,我是否减小了图例框内文本的字体大小,以便图例框的大小变小。

采纳答案by Navi

You can make the legend text smaller by creating font properties:

您可以通过创建字体属性来缩小图例文本:

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

回答by Christian Alis

To place the legend outside the plot area, use locand bbox_to_anchorkeywords of legend(). For example, the following code will place the legend to the right of the plot area:

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

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

For more info, see the legend guide

有关更多信息,请参阅图例指南

回答by Joe Kington

There are a number of ways to do what you want. To add to what @inalis and @Navi already said, you can use the bbox_to_anchorkeyword argument to place the legend partially outside the axes and/or decrease the font size.

有很多方法可以做你想做的事。要添加@inalis 和@Navi 已经说过的内容,您可以使用bbox_to_anchor关键字参数将图例部分放置在轴之外和/或减小字体大小。

Before you consider decreasing the font size (which can make things awfully hard to read), try playing around with placing the legend in different places:

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

So, let's start with a generic example:

因此,让我们从一个通用示例开始:

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

alt text

替代文字

If we do the same thing, but use the bbox_to_anchorkeyword argument we can shift the legend slightly outside the axes boundaries:

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

alt text

替代文字

Similarly, you can make the legend more horizontal and/or put it at the top of the figure (I'm also turning on rounded corners and a simple drop shadow):

同样,您可以使图例更加水平和/或将其放在图的顶部(我还打开了圆角和简单的投影):

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

alt text

替代文字

Alternatively, you can shrink the current plot's width, and put the legend entirely outside the axis of the figure (note: if you use tight_layout(), then leave out ax.set_position():

或者,您可以缩小当前绘图的宽度,并将图例完全放在图形轴之外(注意:如果您使用tiny_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()

alt text

替代文字

And in a similar manner, you can shrink the plot vertically, and put the a horizontal legend at the bottom:

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

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

alt text

替代文字

Have a look at the matplotlib legend guide. You might also take a look at plt.figlegend().

看看matplotlib图例指南。你也可以看看plt.figlegend()

回答by Uri Laserson

You can also try figlegend. It is possible to create a legend independent of any Axes object. However, you may need to create some "dummy" Paths to make sure the formatting for the objects gets passed on correctly.

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

回答by mefathy

Short Answer: Invoke draggable on the legend and interactively move it wherever you want:

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

ax.legend().draggable()

Long Answer: If you rather prefer to place the legend interactively/manually rather than programmatically, you can toggle the draggable mode of the legend so that you can drag it to wherever you want. Check the example below:

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

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

回答by Martin

Something along these lines worked for me. Starting with a bit of code taken from Joe, this method modifies the window width to automatically fit a legend to the right of the figure.

沿着这些路线的东西对我有用。从 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()

回答by Mateo Sanchez

As noted, you could also place the legend in the plot, or slightly off it to the edge as well. Here is an example using the Plotly Python API, made with an IPython Notebook. I'm on the team.

如前所述,您也可以将图例放在图中,或者也可以稍微放在边缘。下面是一个使用Plotly Python API的例子,它是用IPython Notebook 制作的。我在队里。

To begin, you'll want to install the necessary packages:

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

import plotly
import math
import random
import numpy as np

Then, install Plotly:

然后,安装 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)

This creates your graph, and allows you a chance to keep the legend within the plot itself. The default for the legend if it is not set is to place it in the plot, as shown here.

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

enter image description here

在此处输入图片说明

For an alternative placement, you can closely align the edge of the graph and border of the legend, and remove border lines for a closer fit.

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

enter image description here

在此处输入图片说明

You can move and re-style the legend and graph with code, or with the GUI. To shift the legend, you have the following options to position the legend inside the graph by assigning x and y values of <= 1. E.g :

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

  • {"x" : 0,"y" : 0}-- Bottom Left
  • {"x" : 1, "y" : 0}-- Bottom Right
  • {"x" : 1, "y" : 1}-- Top Right
  • {"x" : 0, "y" : 1}-- Top Left
  • {"x" :.5, "y" : 0}-- Bottom Center
  • {"x": .5, "y" : 1}-- Top Center
  • {"x" : 0,"y" : 0}- 左下方
  • {"x" : 1, "y" : 0}-- 右下角
  • {"x" : 1, "y" : 1}- 右上
  • {"x" : 0, "y" : 1}- 左上方
  • {"x" :.5, "y" : 0}-- 底部中心
  • {"x": .5, "y" : 1}-- 顶级中心

In this case, we choose the upper right, legendstyle = {"x" : 1, "y" : 1}, also described in the documentation:

在这种情况下,我们选择右上角,legendstyle = {"x" : 1, "y" : 1},也在文档中描述:

enter image description here

在此处输入图片说明

回答by Bastiaan

Not exactly what you asked for, but I found it's an alternative for the same problem. Make the legend semi-transparant, like so: matplotlib plot with semi transparent legend and semitransparent text box

不完全是您所要求的,但我发现它是同一问题的替代方案。使图例半透明,如下所示: 带有半透明图例和半透明文本框的 matplotlib 图

Do this with:

这样做:

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)

回答by radtek

Here is an example from the matplotlib tutorial found here. This is one of the more simpler examples but I added transparency to the legend and added plt.show() so you can paste this into the interactive shell and get a result:

下面是从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()

回答by Shital Shah

Just call legend()call after the plot()call like this:

只需像这样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))

Results would look something like this:

结果看起来像这样:

enter image description here

在此处输入图片说明