【问题标题】:Move and resize legends-box in matplotlib在 matplotlib 中移动和调整图例框的大小
【发布时间】:2014-06-07 22:00:17
【问题描述】:

我正在使用 Matplotlib 创建绘图,并将其保存为 SVG,使用 Inkscape 导出为 .pdf + .pdf_tex,并将 .pdf_tex 文件包含在 LaTeX 文档中。

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

当我在我的 LaTeX 文档中使用它时呈现这样的效果。请注意,轴上数字的字体发生了变化,并且图例中的 LaTeX 代码已编译:

绘图代码(此处未显示如何导出为 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()

如您所见,问题在于图例周围的框的对齐方式和大小是错误的。这是因为图片通过 Inkscape + pdflatex 时标签的文字大小发生了变化(因为\footnotesize 等消失了,字体大小发生了变化)。

我发现我可以选择标签的位置

plt.label(loc = 'upper right')

或者如果我想要更多的控制权,我可以使用

plt.label(bbox_to_anchor = [0.5, 0.2])

但我还没有找到任何使标签周围的框变小的方法。这可能吗?

使盒子变小的另一种方法是使用类似的东西删除盒子的轮廓

legend = plt.legend()
legend.get_frame().set_edgecolor('1.0')

然后将标签移动到我想要的位置。在这种情况下,我希望能够通过首先让 python/matplotlib 使用来设置标签的位置

plt.label(loc = 'upper right')

然后例如将其向右移动一点。这可能吗?我尝试过使用get_bbox_to_anchor()set_bbox_to_anchor(),但似乎无法正常工作。

【问题讨论】:

  • 我在寻找 loc 关键字 - upper left 等并到达这里。

标签: python matplotlib legend


【解决方案1】:

您可以通过绘制自动放置图例后移动它,然后获取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()

【讨论】:

  • 这看起来很棒。我以前从未见过legendPatch,为什么docs 中没有提到它?
  • 我不知道。我从 Matplotlib-users 电子邮件列表中学到了这个技巧,但我找不到该帖子。希望其他人能提供更完整的答案!
  • 这不适用于 matplotlib 版本 '1.5.1+1304.gc0728d2' matplotlib/transforms.py in get_points(self) 1101 # same. 1102 points = self._transform.transform( -> 1103 [[p[0, 0], p[0, 1]], 1104 [p[1, 0], p[0, 1]], 1105 [p[0, 0], p[1, 1]], TypeError: list indices must be integers, not tuple
  • @DimaLituiev 我已经修改了答案,现在它可以在 matplotlib 1.5.1 上按预期工作。
  • 对我来说效果很好。在将变量 yOffset 设置为所需大小后,您还可以使用 bb.y0 += yOffsetbb.y1 += yOffset 垂直移动图例。
【解决方案2】:

您可以使用bbox_to_anchorbbox_transform 参数来帮助您设置图例的锚点:

ax = plt.gca()
plt.legend(bbox_to_anchor=(1.1, 1.1), bbox_transform=ax.transAxes)

请注意,(1.1, 1.1) 在此示例中位于坐标区坐标中。如果您想使用数据坐标,则必须改用bbox_transform=ax.transData

【讨论】:

  • 谢谢。但是,这并不允许我在放置图例后移动它。顺便说一句,transAxes 实际上是根据doc 的默认值。
  • @FilipSund,是的,transAxes 是默认值...您也许可以将具有 4 个浮点数(x、y、宽度、高度)的元组传递给 bbox_to_achor,这应该会给您对 bbox 行为的更多控制...
猜你喜欢
  • 2010-11-19
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 2021-10-02
  • 2015-06-08
  • 2014-07-21
  • 2018-07-14
  • 2013-09-17
相关资源
最近更新 更多