ihuston
ihuston

Reputation: 923

Can matplotlib add metadata to saved figures?

I want to be able to ascertain the provenance of the figures I create using matplotlib, i.e. to know which version of my code and data created these figures. (See this essay for more on provenance.)

I imagine the most straightforward approach would be to add the revision numbers of the code and data to the metadata of the saved figures, or as comments in a postscript file for example.

Is there any easy way to do this in Matplotlib? The savefig function doesn't seem to be capable of this but has someone come up with a workable solution?

Upvotes: 35

Views: 9227

Answers (6)

J B
J B

Reputation: 440

In another slight variation of some of the above answers for saved images, matplotlib.pyplot.imsave has a pil_kwargs keyword. This allows to specify the PIL.PngImagePlugin.PngInfo() metadata directly, and so you don't need to use the PIL Image syntax.

Upvotes: 0

Sebapi
Sebapi

Reputation: 209

This is an old question but there should be an updated answer.

matplotlib now accepts a metadata dictionary as parameter. Using the creator tag is allowed for svg, png.

from matplotlib import pyplot as plt
plt.plot([1,2],[1,4])
f = "line.png"
metadata={"Creator":"them"}
plt.savefig(filename,metadata=metadata)
plt.close()

Note that for png file, inspecting the metadata is hard, as gimp won't see it. The python PIL library allows to extract it:

from PIL import Image
im2 = Image.open(f)
print(im2.info)

>{'Software': 'Matplotlib version3.6.2, https://matplotlib.org/', 'Creator': 'them', 'dpi': (100, 100)}

Upvotes: 1

JoeZuntz
JoeZuntz

Reputation: 1169

As of matplotlib version 2.1.0, the savefig command accepts the keyword argument metadata. You pass in a dictionary with string key/value pairs to be saved.

This only fully works with the 'agg' backend for PNG files.

For PDF and PS files you can use a pre-defined list of tags.

Upvotes: 12

Mark
Mark

Reputation: 3565

If you are generating SVG files, you can simply append text as an XML comment at the end of the SVG file. Editors like Inkscape appear to preserve this text, even if you subsequently edit an image.

Here's an example, based on the answer from 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")

Upvotes: 3

Alessandro
Alessandro

Reputation: 371

If you are interested in PDF files, then you can have a look at the matplotlib module matplotlib.backends.backend_pdf. At this link there is a nice example of its usage, which could be "condensed" into the following:

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

Upvotes: 11

Hooked
Hooked

Reputation: 88118

I don't know of a way using matplotlib, but you can add metadata to png's with PIL:

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

This gives:

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

Upvotes: 21

Related Questions