如何将图例放在情节之外

发布于 2024-10-12 18:20:21 字数 163 浏览 9 评论 0 原文

我有一系列 20 个图(不是子图)要在一个图中绘制。我希望图例是在盒子之外的。同时,我不想更改轴,因为图形的尺寸会减小。

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

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.

  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 a way to reduce the font size of the text inside the legend box, so that the size of the legend box will be small?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(18

意中人 2024-10-19 18:20:21

有很多种方法可以做你想做的事。添加到 什么 Christian Alis 和 < a href="https://stackoverflow.com/questions/4700614/how-to-put-the-legend-outside-the-plot/4700674#4700674">Navi 已经说了,你可以使用 < code>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 range(5):
    ax.plot(x, i * x, label='$y = %ix

alt text

如果我们做同样的事情,但使用 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 range(5):
    ax.plot(x, i * x, label='$y = %ix

Alt text

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

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

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

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

alt text

或者,缩小当前绘图的宽度,并将图例完全放在图形的轴之外(注意:如果您使用 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 range(5):
    ax.plot(x, i * x, label='$y = %ix

Alt text

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

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

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

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

Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend() plt.show()

alt text

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


Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend(bbox_to_anchor=(1.1, 1.05)) plt.show()

Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend() plt.show()

alt text

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


Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

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

alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend() plt.show()

alt text

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


Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend(bbox_to_anchor=(1.1, 1.05)) plt.show()

Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend() plt.show()

alt text

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


Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

%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

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend() plt.show()

alt text

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


Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend(bbox_to_anchor=(1.1, 1.05)) plt.show()

Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend() plt.show()

alt text

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


Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

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

alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend() plt.show()

alt text

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


Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend(bbox_to_anchor=(1.1, 1.05)) plt.show()

Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend() plt.show()

alt text

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


Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

%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

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend() plt.show()

alt text

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


Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend(bbox_to_anchor=(1.1, 1.05)) plt.show()

Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend() plt.show()

alt text

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


Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

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

alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend() plt.show()

alt text

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


Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend(bbox_to_anchor=(1.1, 1.05)) plt.show()

Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend() plt.show()

alt text

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


Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

%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

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend() plt.show()

alt text

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


Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend(bbox_to_anchor=(1.1, 1.05)) plt.show()

Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend() plt.show()

alt text

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


Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

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

alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend() plt.show()

alt text

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


Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend(bbox_to_anchor=(1.1, 1.05)) plt.show()

Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

% i) ax.legend() plt.show()

alt text

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


Alt text

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


alt text

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


Alt text

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


Alt text

看一下 matplotlib 图例指南。您还可以查看 plt.figlegend()

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

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 range(5):
    ax.plot(x, i * x, label='$y = %ix

alt text

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

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

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

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

Alt text

Similarly, 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 range(5):
    line, = ax.plot(x, i * x, label='$y = %ix

alt text

Alternatively, 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():

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

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

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

Alt text

And in a similar manner, shrink the plot vertically, and put 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 range(5):
    line, = ax.plot(x, i * x, label='$y = %ix

Alt text

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

% i) ax.legend() plt.show()

alt text

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


Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend(bbox_to_anchor=(1.1, 1.05)) plt.show()

Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend() plt.show()

alt text

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


Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

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

alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend() plt.show()

alt text

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


Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend(bbox_to_anchor=(1.1, 1.05)) plt.show()

Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend() plt.show()

alt text

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


Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

%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, shrink the plot vertically, and put a horizontal legend at the bottom:


Alt text

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

% i) ax.legend() plt.show()

alt text

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


Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend(bbox_to_anchor=(1.1, 1.05)) plt.show()

Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend() plt.show()

alt text

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


Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

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

alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend() plt.show()

alt text

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


Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend(bbox_to_anchor=(1.1, 1.05)) plt.show()

Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend() plt.show()

alt text

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


Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

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

% i) ax.legend() plt.show()

alt text

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


Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend(bbox_to_anchor=(1.1, 1.05)) plt.show()

Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend() plt.show()

alt text

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


Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

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

alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend() plt.show()

alt text

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


Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend(bbox_to_anchor=(1.1, 1.05)) plt.show()

Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend() plt.show()

alt text

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


Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

%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, shrink the plot vertically, and put a horizontal legend at the bottom:


Alt text

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

% i) ax.legend() plt.show()

alt text

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


Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend(bbox_to_anchor=(1.1, 1.05)) plt.show()

Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend() plt.show()

alt text

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


Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

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

alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend() plt.show()

alt text

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


Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend(bbox_to_anchor=(1.1, 1.05)) plt.show()

Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

% i) ax.legend() plt.show()

alt text

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


Alt text

Similarly, 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):


alt text

Alternatively, 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():


Alt text

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


Alt text

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

热风软妹 2024-10-19 18:20:21

放置图例 (bbox_to_anchor)

使用 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))

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

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

将图例放置在坐标区之外,使图例的左上角位于坐标区 (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")

有关如何将 4 元组参数解释为 bbox_to_anchor(如 l4)的详细信息,请参阅 这个问题mode="expand" 在 4 元组给出的边界框内水平扩展图例。有关垂直展开的图例,请参阅此问题

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

后处理

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

此问题的解决方案是:

  • 调整子图参数
    通过使用 plt.subplots_adjust。例如,

    <前><代码>plt.subplots_调整(右= 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")
    
  • 自动调整子图参数
    可以在此答案中找到一种自动调整子图位置以使图例适合画布而不更改图形大小的方法:创建具有精确尺寸且无填充的图形(以及轴外的图例)

上面讨论的情况之间的比较:

在此处输入图像描述

替代方案

A图例

人们可以使用图例代替轴,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 子图 lax.legend(h, l) 中的图例。下面是一个完整的示例。

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 图例指南 以及您其他内容的一些示例想做传奇。
  • 可以直接在回答此问题时找到一些用于放置饼图图例的示例代码: Python - 图例与饼图重叠
  • loc 参数可以采用数字而不是字符串,这使得调用更短,但是,它们彼此之间的映射不是很直观。以下是供参考的映射:

在此处输入图像描述

Placing the legend (bbox_to_anchor)

A legend is positioned inside the bounding box of the axes using the loc argument to plt.legend.
E.g., loc="upper right" places the legend in the upper right corner of the bounding box, which by default extents from (0, 0) to (1, 1) in axes coordinates (or in bounding box notation (x0, y0, width, height) = (0, 0, 1, 1)).

To place the legend outside of the axes bounding box, one may specify a tuple (x0, y0) of axes coordinates of the lower left corner of the legend.

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

A more versatile approach is to manually specify the bounding box into which the legend should be placed, using the bbox_to_anchor argument. One can restrict oneself to supply only the (x0, y0) part of the bbox. This creates a zero span box, out of which the legend will expand in the direction given by the loc argument. E.g.,

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

places the legend outside the axes, such that the upper left corner of the legend is at position (1.04, 1) in axes coordinates.

Further examples are given below, where additionally the interplay between different arguments like mode and ncols are shown.

Enter image description here

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

Details about how to interpret the 4-tuple argument to bbox_to_anchor, as in l4, can be found in this question. The mode="expand" expands the legend horizontally inside the bounding box given by the 4-tuple. For a vertically expanded legend, see this question.

Sometimes it may be useful to specify the bounding box in figure coordinates instead of axes coordinates. This is shown in the example l5 from above, where the bbox_transform argument is used to put the legend in the lower left corner of the figure.

Postprocessing

Having placed the legend outside the axes often leads to the undesired situation that it is completely or partially outside the figure canvas.

Solutions to this problem are:

  • Adjust the subplot parameters
    One can adjust the subplot parameters such, that the axes take less space inside the figure (and thereby leave more space to the legend) by using plt.subplots_adjust. E.g.,

    plt.subplots_adjust(right=0.7)
    

    leaves 30% space on the right-hand side of the figure, where one could place the legend.

  • Tight layout
    Using plt.tight_layout Allows to automatically adjust the subplot parameters such that the elements in the figure sit tight against the figure edges. Unfortunately, the legend is not taken into account in this automatism, but we can supply a rectangle box that the whole subplots area (including labels) will fit into.

    plt.tight_layout(rect=[0, 0, 0.75, 1])
    
  • Saving the figure with bbox_inches = "tight"
    The argument bbox_inches = "tight" to plt.savefig can be used to save the figure such that all artist on the canvas (including the legend) are fit into the saved area. If needed, the figure size is automatically adjusted.

    plt.savefig("output.png", bbox_inches="tight")
    
  • Automatically adjusting the subplot parameters
    A way to automatically adjust the subplot position such that the legend fits inside the canvas without changing the figure size can be found in this answer: Creating figure with exact size and no padding (and legend outside the axes)

Comparison between the cases discussed above:

Enter image description here

Alternatives

A figure legend

One may use a legend to the figure instead of the axes, matplotlib.figure.Figure.legend. This has become especially useful for Matplotlib version 2.1 or later, where no special arguments are needed

fig.legend(loc=7)

to create a legend for all artists in the different axes of the figure. The legend is placed using the loc argument, similar to how it is placed inside an axes, but in reference to the whole figure - hence it will be outside the axes somewhat automatically. What remains is to adjust the subplots such that there is no overlap between the legend and the axes. Here the point "Adjust the subplot parameters" from above will be helpful. An example:

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

Enter image description here

Legend inside dedicated subplot axes

An alternative to using bbox_to_anchor would be to place the legend in its dedicated subplot axes (lax).
Since the legend subplot should be smaller than the plot, we may use gridspec_kw={"width_ratios":[4, 1]} at axes creation.
We can hide the axes lax.axis("off"), but we still put a legend in. The legend handles and labels need to obtained from the real plot via h, l = ax.get_legend_handles_labels() and can then be supplied to the legend in the lax subplot, lax.legend(h, l). A complete example is below.

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

This produces a plot which is visually pretty similar to the plot from above:

Enter image description here

We could also use the first axes to place the legend, but use the bbox_transform of the legend axes,

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

In this approach, we do not need to obtain the legend handles externally, but we need to specify the bbox_to_anchor argument.

Further reading and notes:

  • Consider the Matplotlib legend guide with some examples of other stuff you want to do with legends.
  • Some example code for placing legends for pie charts may directly be found in answer to this question: Python - Legend overlaps with the pie chart
  • The loc argument can take numbers instead of strings, which make calls shorter, however, they are not very intuitively mapped to each other. Here is the mapping for reference:

Enter image description here

驱逐舰岛风号 2024-10-19 18:20:21

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

结果如下所示:

在此处输入图像描述

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

# 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

音盲 2024-10-19 18:20:21
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')
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)

Enter image description here

  • fontsize='xx-small' also works, without importing FontProperties.
plt.legend(handles=[p1, p2], title='title', bbox_to_anchor=(1.05, 1), loc='upper left', fontsize='xx-small')
七秒鱼° 2024-10-19 18:20:21

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

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

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

To place the legend outside the plot area, use loc and bbox_to_anchor keywords of legend(). For example, the following code will place the legend to the right of the plot area:

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

For more info, see the legend guide

多情出卖 2024-10-19 18:20:21

简短回答:您可以使用 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')

示例(我只更改了最后一行,向 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 本机允许图例框的外部位置为 < a href="http://www.mathworks.com/help/matlab/ref/legend.html" rel="noreferrer">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])

在此处输入图像描述

Short answer: you can use bbox_to_anchor + bbox_extra_artists + bbox_inches='tight'.


Longer answer:
You can use bbox_to_anchor to manually specify the location of the legend box, as some other people have pointed out in the answers.

However, the usual issue is that the legend box is cropped, e.g.:

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

enter image description here

In order to prevent the legend box from getting cropped, when you save the figure you can use the parameters bbox_extra_artists and bbox_inches to ask savefig to include cropped elements in the saved image:

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

Example (I only changed the last line to add 2 parameters to 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')

enter image description here

I wish that matplotlib would natively allow outside location for the legend box as 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])

enter image description here

爱给你人给你 2024-10-19 18:20:21

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

pylab.legend(loc='best')

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

比较 loc='best'

但是,如果没有地方放置图例而不与数据重叠,那么你会想尝试其他答案之一;使用 loc="best" 永远不会将图例放在绘图之外

In addition to all the excellent answers here, newer versions of matplotlib and pylab can automatically determine where to put the legend without interfering with the plots, if possible.

pylab.legend(loc='best')

This will automatically place the legend away from the data if possible!

Compare the use of loc='best'

However, if there isn't any place to put the legend without overlapping the data, then you'll want to try one of the other answers; using loc="best" will never put the legend outside of the plot.

提笔书几行 2024-10-19 18:20:21

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

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

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()
独﹏钓一江月 2024-10-19 18:20:21

matplotlib 3.7 中的新增功能

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

  1. 确保布局是“约束”的
  2. 使用 fig.legend (不是 plt.legendax.legend
  3. 在位置字符串前面添加“outside”
import matplotlib.pyplot as plt
import numpy as np

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

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

多个子图也可以很好地使用新的“外部”位置:

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

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

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

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

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

) 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') #2 #3 plt.show()

多个子图也可以很好地使用新的“外部”位置:


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



) ax1.plot(x, np.sin(x), '--', label='$f(x) = sin(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') #2 #3 plt.show()

多个子图也可以很好地使用新的“外部”位置:


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



) ax2.plot(x, np.cos(x), ':', label='$f(x) = cos(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') #2 #3 plt.show()

多个子图也可以很好地使用新的“外部”位置:


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



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

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



) 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') #2 #3 plt.show()

多个子图也可以很好地使用新的“外部”位置:


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



New in matplotlib 3.7

Figure legends now accept "outside" locations directly, e.g., loc='outside right upper'.

  1. Make sure the layout is "constrained"
  2. Use fig.legend (not plt.legend or ax.legend)
  3. Prepend "outside" to the location string
import matplotlib.pyplot as plt
import numpy as np

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

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

Multiple subplots also work fine with the new "outside" locations:

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

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

Note that the available "outside" locations are preset, so use the older answers if you need finer positioning. However the standard locations should fit most use cases:

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

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

) ax.plot(x, np.sin(x), label='$f(x) = sin(x)

Multiple subplots also work fine with the new "outside" locations:


Note that the available "outside" locations are preset, so use the older answers if you need finer positioning. However the standard locations should fit most use cases:



) ax.plot(x, np.cos(x), label='$f(x) = cos(x)

Multiple subplots also work fine with the new "outside" locations:


Note that the available "outside" locations are preset, so use the older answers if you need finer positioning. However the standard locations should fit most use cases:



) fig.legend(loc='outside right upper') #2 #3 plt.show()

Multiple subplots also work fine with the new "outside" locations:


Note that the available "outside" locations are preset, so use the older answers if you need finer positioning. However the standard locations should fit most use cases:



) ax1.plot(x, np.sin(x), '--', label='$f(x) = sin(x)

Note that the available "outside" locations are preset, so use the older answers if you need finer positioning. However the standard locations should fit most use cases:



) ax.plot(x, np.sin(x), label='$f(x) = sin(x)

Multiple subplots also work fine with the new "outside" locations:


Note that the available "outside" locations are preset, so use the older answers if you need finer positioning. However the standard locations should fit most use cases:



) ax.plot(x, np.cos(x), label='$f(x) = cos(x)

Multiple subplots also work fine with the new "outside" locations:


Note that the available "outside" locations are preset, so use the older answers if you need finer positioning. However the standard locations should fit most use cases:



) fig.legend(loc='outside right upper') #2 #3 plt.show()

Multiple subplots also work fine with the new "outside" locations:


Note that the available "outside" locations are preset, so use the older answers if you need finer positioning. However the standard locations should fit most use cases:



) ax2.plot(x, np.cos(x), ':', label='$f(x) = cos(x)

Note that the available "outside" locations are preset, so use the older answers if you need finer positioning. However the standard locations should fit most use cases:



) ax.plot(x, np.sin(x), label='$f(x) = sin(x)

Multiple subplots also work fine with the new "outside" locations:


Note that the available "outside" locations are preset, so use the older answers if you need finer positioning. However the standard locations should fit most use cases:



) ax.plot(x, np.cos(x), label='$f(x) = cos(x)

Multiple subplots also work fine with the new "outside" locations:


Note that the available "outside" locations are preset, so use the older answers if you need finer positioning. However the standard locations should fit most use cases:



) fig.legend(loc='outside right upper') #2 #3 plt.show()

Multiple subplots also work fine with the new "outside" locations:


Note that the available "outside" locations are preset, so use the older answers if you need finer positioning. However the standard locations should fit most use cases:



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

Note that the available "outside" locations are preset, so use the older answers if you need finer positioning. However the standard locations should fit most use cases:



) ax.plot(x, np.sin(x), label='$f(x) = sin(x)

Multiple subplots also work fine with the new "outside" locations:


Note that the available "outside" locations are preset, so use the older answers if you need finer positioning. However the standard locations should fit most use cases:



) ax.plot(x, np.cos(x), label='$f(x) = cos(x)

Multiple subplots also work fine with the new "outside" locations:


Note that the available "outside" locations are preset, so use the older answers if you need finer positioning. However the standard locations should fit most use cases:



) fig.legend(loc='outside right upper') #2 #3 plt.show()

Multiple subplots also work fine with the new "outside" locations:


Note that the available "outside" locations are preset, so use the older answers if you need finer positioning. However the standard locations should fit most use cases:



海夕 2024-10-19 18:20:21

新版本的 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()

这会导致以下绘图:

图例位于外部

参考文献:

Newer versions of Matplotlib have made it much easier to position the legend outside the plot. I produced this example with Matplotlib version 3.1.1.

Users can pass a 2-tuple of coordinates to the loc parameter to position the legend anywhere in the bounding box. The only gotcha is you need to run plt.tight_layout() to get matplotlib to recompute the plot dimensions so the legend is visible:

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

This leads to the following plot:

Plot with legend outside

References:

乱世争霸 2024-10-19 18:20:21

这并不完全是您所要求的,但我发现它是同一问题的替代方案。

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

Matplotlibplot with semitransparent legend and semitransparent text box

执行此操作:

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)

It is not exactly what you asked for, but I found it's an alternative for the same problem.

Make the legend semitransparent, like so:

Matplotlib plot with semitransparent legend and semitransparent text box

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)
情话墙 2024-10-19 18:20:21

如前所述,您还可以将图例放置在图中,或者稍微偏离边缘。以下是使用 Plotly Python 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)!}

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

在此处输入图像描述

对于替代放置,您可以紧密对齐图形边缘和图例边框,然后删除边框线更贴合。

在此处输入图像描述

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

  • {"x" : 0,"y" : 0} -- 左下
  • {"x" : 1, "y" : 0} -- 右下
  • {"x" : 1, "y" : 1} - - 右上
  • {"x" : 0, "y" : 1} -- 左上
  • {"x" :.5, "y" : 0} -- Bottom Center
  • {"x": .5, "y" : 1} -- Top Center

在本例中,我们选择右上角,legendstyle = {"x" : 1, " y" : 1},也在文档中进行了描述:

在此处输入图像描述

, '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\\\\

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

在此处输入图像描述

对于替代放置,您可以紧密对齐图形边缘和图例边框,然后删除边框线更贴合。

在此处输入图像描述

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

  • {"x" : 0,"y" : 0} -- 左下
  • {"x" : 1, "y" : 0} -- 右下
  • {"x" : 1, "y" : 1} - - 右上
  • {"x" : 0, "y" : 1} -- 左上
  • {"x" :.5, "y" : 0} -- Bottom Center
  • {"x": .5, "y" : 1} -- Top Center

在本例中,我们选择右上角,legendstyle = {"x" : 1, " y" : 1},也在文档中进行了描述:

在此处输入图像描述

},\ {'x':x, 'y':sin(x,2), 'line':{'color':'#7f7f7f'},'name':'$ x-\\frac{x^3}{6}

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

在此处输入图像描述

对于替代放置,您可以紧密对齐图形边缘和图例边框,然后删除边框线更贴合。

在此处输入图像描述

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

  • {"x" : 0,"y" : 0} -- 左下
  • {"x" : 1, "y" : 0} -- 右下
  • {"x" : 1, "y" : 1} - - 右上
  • {"x" : 0, "y" : 1} -- 左上
  • {"x" :.5, "y" : 0} -- Bottom Center
  • {"x": .5, "y" : 1} -- Top Center

在本例中,我们选择右上角,legendstyle = {"x" : 1, " y" : 1},也在文档中进行了描述:

在此处输入图像描述

},\ {'x':x, 'y':sin(x,3), 'line':{'color':'#bcbd22'},'name':'$ x-\\frac{x^3}{6}+\\frac{x^5}{120}

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

在此处输入图像描述

对于替代放置,您可以紧密对齐图形边缘和图例边框,然后删除边框线更贴合。

在此处输入图像描述

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

  • {"x" : 0,"y" : 0} -- 左下
  • {"x" : 1, "y" : 0} -- 右下
  • {"x" : 1, "y" : 1} - - 右上
  • {"x" : 0, "y" : 1} -- 左上
  • {"x" :.5, "y" : 0} -- Bottom Center
  • {"x": .5, "y" : 1} -- Top Center

在本例中,我们选择右上角,legendstyle = {"x" : 1, " y" : 1},也在文档中进行了描述:

在此处输入图像描述

},\ {'x':x, 'y':sin(x,4), 'line':{'color':'#17becf'},'name':'$ x-\\frac{x^5}{120}

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

在此处输入图像描述

对于替代放置,您可以紧密对齐图形边缘和图例边框,然后删除边框线更贴合。

在此处输入图像描述

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

  • {"x" : 0,"y" : 0} -- 左下
  • {"x" : 1, "y" : 0} -- 右下
  • {"x" : 1, "y" : 1} - - 右上
  • {"x" : 0, "y" : 1} -- 左上
  • {"x" :.5, "y" : 0} -- Bottom Center
  • {"x": .5, "y" : 1} -- Top Center

在本例中,我们选择右上角,legendstyle = {"x" : 1, " y" : 1},也在文档中进行了描述:

在此处输入图像描述

}], 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} -- Bottom Center
  • {"x": .5, "y" : 1} -- Top Center

在本例中,我们选择右上角,legendstyle = {"x" : 1, " y" : 1},也在文档中进行了描述:

在此处输入图像描述

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.

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

import plotly
import math
import random
import numpy as np

Then, install 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)!}

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 :

  • {"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

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

enter image description here

, '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\\\\

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 :

  • {"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

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

enter image description here

},\ {'x':x, 'y':sin(x,2), 'line':{'color':'#7f7f7f'},'name':'$ x-\\frac{x^3}{6}

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 :

  • {"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

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

enter image description here

},\ {'x':x, 'y':sin(x,3), 'line':{'color':'#bcbd22'},'name':'$ x-\\frac{x^3}{6}+\\frac{x^5}{120}

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 :

  • {"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

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

enter image description here

},\ {'x':x, 'y':sin(x,4), 'line':{'color':'#17becf'},'name':'$ x-\\frac{x^5}{120}

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 :

  • {"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

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

enter image description here

}], 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 :

  • {"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

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

enter image description here

余生再见 2024-10-19 18:20:21

我只是使用字符串 'center left' 作为位置,就像 MATLAB< /a>.

我从 Matplotlib 导入了 pyplot。

代码如下:

import matplotlib.pyplot 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)

在此处输入图像描述

I simply used the string 'center left' for the location, like in MATLAB.

I imported pyplot from Matplotlib.

See the code as follows:

import matplotlib.pyplot 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)

Enter image description here

迷你仙 2024-10-19 18:20:21

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

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.

原谅过去的我 2024-10-19 18:20:21

这是另一个解决方案,类似于添加 bbox_extra_artistsbbox_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")

Here's another solution, similar to adding bbox_extra_artists and bbox_inches, where you don't have to have your extra artists in the scope of your savefig call. I came up with this since I generate most of my plot inside functions.

Instead of adding all your additions to the bounding box when you want to write it out, you can add them ahead of time to the Figure's artists. Using something similar to 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")

Here's the generated plot.

不寐倦长更 2024-10-19 18:20:21

这些方面的一些东西对我有用。从 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()

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.

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()
自由如风 2024-10-19 18:20:21

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

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

The solution that worked for me when I had a huge legend was to use an extra empty image layout.

In the following example, I made four rows and at the bottom I plotted the image with an offset for the legend (bbox_to_anchor). At the top it does not get cut.

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')
灼疼热情 2024-10-19 18:20:21

以下是 此处 中的 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()

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:

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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文