Python 在 matplotlib 中移动和调整图例框的大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23238041/
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
Move and resize legends-box in matplotlib
提问by Filip S.
I'm creating plots using Matplotlib that I save as SVG, export to .pdf + .pdf_tex using Inkscape, and include the .pdf_tex-file in a LaTeX document.
我正在使用 Matplotlib 创建绘图,我将其另存为 SVG,使用 Inkscape 导出到 .pdf + .pdf_tex,并将 .pdf_tex 文件包含在 LaTeX 文档中。
This means that I can input LaTeX-commands in titles, legends etc., giving an image like this

这意味着我可以在标题、图例等中输入 LaTeX 命令,给出这样的图像

which renders like this when I use it in my LaTeX document. Notice that the font for the numbers on the axes change, and the LaTeX-code in the legend is compiled:
当我在我的 LaTeX 文档中使用它时呈现出这样的效果。请注意,轴上数字的字体发生了变化,并且图例中的 LaTeX 代码已编译:


Code for the plot (how to export to SVG not shown here, but can be shown on request):
绘图代码(此处未显示如何导出到 SVG,但可以根据要求显示):
import numpy as np
x = np.linspace(0,1,100)
y = x**2
import matplotlib.pyplot as plt
plt.plot(x, y, label = '{\footnotesize $y = x^2$}')
plt.legend(loc = 'best')
plt.show()
The problem is, as you can see, that the alignment and size of the box around the legend is wrong. This is because the size of the text of the label changes when the image is passed through Inkscape + pdflatex (because \footnotesizeetc. disappears, and the font size changes).
问题是,如您所见,图例周围框的对齐方式和大小是错误的。这是因为图片通过Inkscape + pdflatex时label\footnotesize的文字大小会发生变化(因为etc消失,字体大小发生变化)。
I have figured out that I can choose the placement of the label by either
我发现我可以通过以下任一方式选择标签的位置
plt.label(loc = 'upper right')
or if I want more control I can use
或者如果我想要更多的控制,我可以使用
plt.label(bbox_to_anchor = [0.5, 0.2])
but I haven't found any way of making the box around the label smaller. Is this possible?
但我还没有找到任何方法可以使标签周围的框变小。这可能吗?
An alternative to making the box smaller is to remove the outline of the box using something like
使盒子变小的另一种方法是使用类似的东西去除盒子的轮廓
legend = plt.legend()
legend.get_frame().set_edgecolor('1.0')
and then moving the label to where I want it. In that case I would like to be able to set the placement of the label by first letting python/matplotlib place it using
然后将标签移动到我想要的位置。在这种情况下,我希望能够通过首先让 python/matplotlib 使用来设置标签的位置
plt.label(loc = 'upper right')
and then for example moving it a bit to the right. Is this possible? I have tried using get_bbox_to_anchor()and set_bbox_to_anchor(), but can't seem to get it to work.
然后例如将其向右移动一点。这可能吗?我试过使用get_bbox_to_anchor()and set_bbox_to_anchor(),但似乎无法让它工作。
采纳答案by Molly
You can move a legend after automatically placing it by drawing it, and then getting the bbox position. Here's an example:
您可以通过绘制自动放置图例,然后获取bbox位置来移动图例。下面是一个例子:
import matplotlib.pyplot as plt
import numpy as np
# Plot data
x = np.linspace(0,1,100)
y = x**2
fig = plt.figure()
ax = fig.add_subplot(221) #small subplot to show how the legend has moved.
# Create legend
plt.plot(x, y, label = '{\footnotesize $y = x^2$}')
leg = plt.legend( loc = 'upper right')
plt.draw() # Draw the figure so you can find the positon of the legend.
# Get the bounding box of the original legend
bb = leg.get_bbox_to_anchor().inverse_transformed(ax.transAxes)
# Change to location of the legend.
xOffset = 1.5
bb.x0 += xOffset
bb.x1 += xOffset
leg.set_bbox_to_anchor(bb, transform = ax.transAxes)
# Update the plot
plt.show()


回答by Saullo G. P. Castro
You may use the bbox_to_anchorand bbox_transformparameters to help you setting the anchor for your legend:
您可以使用bbox_to_anchor和bbox_transform参数来帮助您为图例设置锚点:
ax = plt.gca()
plt.legend(bbox_to_anchor=(1.1, 1.1), bbox_transform=ax.transAxes)
Note that (1.1, 1.1)are in the axes coordinates in this example. If you wish to use the data coordinates you have to use bbox_transform=ax.transDatainstead.
请注意,(1.1, 1.1)在此示例中位于轴坐标中。如果您希望使用数据坐标,则必须bbox_transform=ax.transData改用。

