10000 Edit error messages for when metadata is passed to `savefig` by ksunden · Pull Request #25430 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Edit error messages for when metadata is passed to savefig #25430

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 14, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions lib/matplotlib/backends/backend_agg.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,9 @@ def buffer_rgba(self):
"""
return self.renderer.buffer_rgba()

def print_raw(self, filename_or_obj):
def print_raw(self, filename_or_obj, metadata=None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be kwonly.

if metadata is not None:
raise ValueError("metadata not supported for raw/rgba")
FigureCanvasAgg.draw(self)
renderer = self.get_renderer()
with cbook.open_file_cm(filename_or_obj, "wb") as fh:
Expand Down Expand Up @@ -518,22 +520,22 @@ def print_to_buffer(self):
# print_figure(), and the latter ensures that `self.figure.dpi` already
# matches the dpi kwarg (if any).

def print_jpg(self, filename_or_obj, *, pil_kwargs=None):
def print_jpg(self, filename_or_obj, *, metadata=None, pil_kwargs=None):
# savefig() has already applied savefig.facecolor; we now set it to
# white to make imsave() blend semi-transparent figures against an
# assumed white background.
with mpl.rc_context({"savefig.facecolor": "white"}):
self._print_pil(filename_or_obj, "jpeg", pil_kwargs)
self._print_pil(filename_or_obj, "jpeg", pil_kwargs, metadata)

print_jpeg = print_jpg

def print_tif(self, filename_or_obj, *, pil_kwargs=None):
self._print_pil(filename_or_obj, "tiff", pil_kwargs)
def print_tif(self, filename_or_obj, *, metadata=None, pil_kwargs=None):
self._print_pil(filename_or_obj, "tiff", pil_kwargs, metadata)

print_tiff = print_tif

def print_webp(self, filename_or_obj, *, pil_kwargs=None):
self._print_pil(filename_or_obj, "webp", pil_kwargs)
def print_webp(self, filename_or_obj, *, metadata=None, pil_kwargs=None):
self._print_pil(filename_or_obj, "webp", pil_kwargs, metadata)

print_jpg.__doc__, print_tif.__doc__, print_webp.__doc__ = map(
"""
Expand Down
5 changes: 5 additions & 0 deletions lib/matplotlib/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -3259,6 +3259,11 @@ def savefig(self, fname, *, transparent=None, **kwargs):
`~.FigureCanvasSVG.print_svg`.
- 'eps' and 'ps' with PS backend: Only 'Creator' is supported.

Not supported for 'pgf', 'raw', and 'rgba' as those formats do not support
embedding metadata.
Does not currently support 'jpg', 'tiff', or 'webp', but may include
embedding EXIF metadata in the future.

bbox_inches : str or `.Bbox`, default: :rc:`savefig.bbox`
Bounding box in inches: only the given portion of the figure is
saved. If 'tight', try to figure out the tight bbox of the figure.
Expand Down
3 changes: 3 additions & 0 deletions lib/matplotlib/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -1610,6 +1610,7 @@ def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None,
Metadata in the image file. The supported keys depend on the output
format, see the documentation of the respective backends for more
information.
Currently only supported for "png", "pdf", "ps", "eps", and "svg".
pil_kwargs : dict, optional
Keyword arguments passed to `PIL.Image.Image.save`. If the 'pnginfo'
key is present, it completely overrides *metadata*, including the
Expand Down Expand Up @@ -1674,6 +1675,8 @@ def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None,
for k, v in metadata.items():
if v is not None:
pnginfo.add_text(k, v)
elif metadata is not None:
raise ValueError(f"metadata not supported for format {format!r}")
if format in ["jpg", "jpeg"]:
format = "jpeg" # Pillow doesn't recognize "jpg".
facecolor = mpl.rcParams["savefig.facecolor"]
Expand Down
11 changes: 11 additions & 0 deletions lib/matplotlib/tests/test_figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1548,3 +1548,14 @@ def test_gridspec_no_mutate_input():
plt.subplots(1, 2, width_ratios=[1, 2], gridspec_kw=gs)
assert gs == gs_orig
plt.subplot_mosaic('AB', width_ratios=[1, 2], gridspec_kw=gs)


@pytest.mark.parametrize('fmt', ['eps', 'pdf', 'png', 'ps', 'svg', 'svgz'])
def test_savefig_metadata(fmt):
Figure().savefig(io.BytesIO(), format=fmt, metadata={})


@pytest.mark.parametrize('fmt', ['jpeg', 'jpg', 'tif', 'tiff', 'webp', "raw", "rgba"])
def test_savefig_metadata_error(fmt):
with pytest.raises(ValueError, match="metadata not supported"):
Figure().savefig(io.BytesIO(), format=fmt, metadata={})
0