Matplotlib 能够为保存的图形添加元数据吗?

34
我希望能够确定使用matplotlib创建的数字的来源,即知道哪个版本的代码和数据创建了这些数字。(有关溯源的更多信息,请参见此文章。)
我想最直接的方法是将代码和数据的修订号添加到保存的数字的元数据中,或者例如在PostScript文件中添加注释。
在Matplotlib中有没有简单的方法可以做到这一点?savefig函数似乎无法实现这一点,但是否有人提出了可行的解决方案?

1
只需在图中添加一些文本即可... - Fredrik Pihl
4
可能很简单,但我不想在提交出版物的数字下面写上“commit 5d3414b19986fe3c08df4088d87b8786a660c387”。 - ihuston
1
我主要使用PDF或EPS,但我认为EXIF对于其他格式也是一个不错的选择。我可能会考虑编写一个包装器来为JPEG添加EXIF字符串,为EPS文件添加注释或向PDF添加元数据。我想知道是否有人已经尝试过这样做。 - ihuston
3
EPS文件只是文本文件,以%开头的行表示注释。因此,您可以轻松地自己添加几行代码。PDF是压缩的EPS(或多或少),因此上述方法也适用于PDF,最好使用一些PDF库进行操作。(我对您追踪来源的努力表示敬意。我一直在跟踪模型运行情况,但迄今为止没有对图表进行过追踪,现在可能会开始了。) - Mauro
1
你曾经写过这样的包装器吗?我很感兴趣。另一种选择是编写一个包装器,仅在每个存储的图像旁边存储一个文本文件。 - gerrit
显示剩余2条评论
4个回答

20

我不知道使用 matplotlib 的方法,但你可以使用 PIL 向 png 添加元数据,详情请参见此处:

f = "test.png"
METADATA = {"version":"1.0", "OP":"ihuston"}

# Create a sample image
import pylab as plt
import numpy as np
X = np.random.random((50,50))
plt.imshow(X)
plt.savefig(f)

# Use PIL to save some image metadata
from PIL import Image
from PIL import PngImagePlugin

im = Image.open(f)
meta = PngImagePlugin.PngInfo()

for x in METADATA:
    meta.add_text(x, METADATA[x])
im.save(f, "png", pnginfo=meta)

im2 = Image.open(f)
print im2.info

这会给出:

{'version': '1.0', 'OP': 'ihuston'}

暂时我打算接受这个答案,因为似乎没有一种方式可以以与格式无关的方式添加 matplotlib 中的元数据。 - ihuston

11

如果您对PDF文件感兴趣,那么可以查看matplotlib模块的matplotlib.backends.backend_pdf。在此链接上有一个很好的使用示例,它可以“压缩”为以下内容:

import pylab as pl
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages

pdffig = PdfPages('figure.pdf')

x=np.arange(10)

pl.plot(x)
pl.savefig(pdffig, format="pdf")

metadata = pdffig.infodict()
metadata['Title'] = 'Example'
metadata['Author'] = 'Pluto'
metadata['Subject'] = 'How to add metadata to a PDF file within matplotlib'
metadata['Keywords'] = 'PdfPages example'

pdffig.close()

9
截至matplotlib版本2.1.0,savefig命令接受关键字参数metadata。您可以传递一个包含字符串键/值对的字典以进行保存。
这仅在PNG文件的'agg'后端中完全有效。
对于PDF和PS文件,您可以使用预定义的标签列表。

3

如果您正在生成SVG文件,您可以将文本作为XML注释附加到SVG文件的末尾。即使您随后编辑了图像,例如使用Inkscape等编辑器,也会保留此文本。

以下是基于Hooked答案的示例:

import pylab as plt
import numpy as np

f = "figure.svg"
X = np.random.random((50,50))
plt.imshow(X)
plt.savefig(f)

open(f, 'a').write("<!-- Here is some invisible metadata. -->\n")

顺便提一下,这个元数据可以在JavaScript中像这样访问:document.getElementsByTagName('svg')[0].nextSibling - MrTomRod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接