我有一个看起来像这样的matplotlib图例:
将标记导出为单独的.pdf文件的简便方法是什么?换句话说,我想最终得到三个单独的.pdf,一个带蓝色X,一个带金色等等。
最终我想做的是在Latex图标题的内联图例中使用这些标记,但我想我会在Latex SE网站上询问该部分。
答案 0 :(得分:1)
将图例句柄导出到文件的想法是将创建的图形保存为pdf,但将其裁剪为感兴趣的部分。
可以通过在bbox
bbox_inches
参数指定一个边界框savefig
来完成此操作
plt.savefig("file.pdf", dpi="figure", bbox_inches=bbox )
现在我们只需找出要使用的边界框。这可以通过为每个图例句柄找到DrawingArea
并将其边界框转换为以英寸为单位的坐标来完成。这是在下面的代码中的函数export_legend_handles
中完成的。
不幸的是,在编写该代码时,我发现该标记可能会超过DrawingArea
。由于我还没有找到一种自动方法来查找DrawingArea
之外的句柄的实际大小,因此可能需要通过某些像素手动扩展/缩小边界框。为此,下面的函数有一个参数d
,它允许设置那些像素偏移量。对于这个测试用例,我已经放入了一些不错的值。
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(422)
x = np.arange(12)
a = np.random.rand(len(x), 3)
markers=["x", "+", "o"]
fig, ax = plt.subplots()
for i in range(a.shape[1]):
ax.plot(x, a[:,i], linestyle="", marker=markers[i], label=markers[i]*6)
leg = ax.legend(framealpha=1)
def export_legend_handles(fig, leg, filename=None, ext=[".pdf", ".png"], d = [0,0,0,3]):
""" d = [left, bottom, right, top] pixel to add in the respective dimension """
import matplotlib.transforms as mtransforms
boxes = []
fig.canvas.draw()
trans = fig.dpi_scale_trans.inverted()
for vpack in leg._legend_handle_box.get_children():
for hpack in vpack.get_children():
drawbox = hpack.get_children()[0]
w, h, xd, yd = drawbox.get_extent(fig.canvas.get_renderer())
ox, oy = drawbox.get_offset()
pixbox = mtransforms.Bbox.from_bounds(ox-d[0],oy-d[1],w+d[0]+d[2],h+d[1]+d[3])
inchbox = pixbox.transformed(trans)
boxes.append(inchbox)
filename = filename if filename else __file__[:-3]
for i, box in enumerate(boxes):
for ex in ext:
plt.savefig(filename+str(i)+ex, dpi="figure", bbox_inches=box)
export_legend_handles(fig, leg, d = [-5,0,-5,3])
plt.show()
这会生成如下图
并将图例句柄保存为pdf和png图像,然后如下所示