Thanks to visit codestin.com
Credit goes to github.com

Skip to content

When comparing eps images, run ghostscript with -dEPSCrop. #24018

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
Sep 28, 2022

Conversation

anntzer
Copy link
Contributor

@anntzer anntzer commented Sep 27, 2022

Currently, the ps backend positions eps images into an imaginary page (the smallest standard page size which can contain the figure size, which happens to be lettersized for the default figure size), setting the %%BoundingBox based on that positioning. But the eps file format doesn't actually record the full page size (that's not the intent of the eps format anyways), just the position of the drawing relative to an origin.

GhostScript is then used to rasterize the eps images during testing; it implicitly assumes a default page size of "letter" (https://ghostscript.readthedocs.io/en/latest/Use.html#choosing-paper-size) which just happens to match the page size selected above. So things are OK... except if the test figure is nondefault and actually bigger than lettersized; in that case ghostscript will just crop out whatever is out of the lettersized paper. Note that such an image comparison test won't fail; it will just fail to compare anything that's outside of the lettersize paper.

Instead, pass -dEPSCrop to GhostScript
(https://ghostscript.readthedocs.io/en/latest/Use.html#depscrop) which readjusts the papersize to match the eps bounding box.

Test e.g. with

import subprocess
from matplotlib.figure import Figure
for fs in [5, 10, 15, 20]:
    Figure(figsize=(fs, fs)).add_subplot().figure.savefig(f"test-{fs}.eps")
    subprocess.run([
        "gs", "-dNOSAFER", "-dNOPAUSE", "-dEPSCrop",
        "-o", f"test-{fs}.png", "-sDEVICE=png16m", f"test-{fs}.eps"])

(Noted while troubleshooting failed tests on mplcairo, which does not perform the centering -- but there were so few tests using eps that the difference in behavior was entirely hidden by the general mplcairo test tolerance, until some more tests were added in matplotlib 3.6.)

Not really a regression, but would still be nice to have this in 3.6.1 to make testing of mplcairo simpler (otherwise I'll just xfail some more tests in mplcairo...).

PR Summary

PR Checklist

Tests and Styling

  • Has pytest style unit tests (and pytest passes).
  • Is Flake 8 compliant (install flake8-docstrings and run flake8 --docstring-convention=all).

Documentation

  • New features are documented, with examples if plot related.
  • New features have an entry in doc/users/next_whats_new/ (follow instructions in README.rst there).
  • API changes documented in doc/api/next_api_changes/ (follow instructions in README.rst there).
  • Documentation is sphinx and numpydoc compliant (the docs should build without error).

Currently, the ps backend positions eps images into an imaginary page
(the smallest standard page size which can contain the figure size,
which happens to be lettersized for the default figure size), setting
the %%BoundingBox based on that positioning.  But the eps file format
doesn't actually record the full page size (that's not the intent of the
eps format anyways), just the position of the drawing relative to an
origin.

GhostScript is then used to rasterize the eps images during testing; it
implicitly assumes a default page size of "letter"
(https://ghostscript.readthedocs.io/en/latest/Use.html#choosing-paper-size)
which just happens to match the page size selected above.  So things are
OK... except if the test figure is nondefault and actually *bigger* than
lettersized; in that case ghostscript will just crop out whatever is out
of the lettersized paper.  Note that such an image comparison test won't
*fail*; it will just fail to compare anything that's outside of the
lettersize paper.

Instead, pass -dEPSCrop to GhostScript
(https://ghostscript.readthedocs.io/en/latest/Use.html#depscrop)
which readjusts the papersize to match the eps bounding box.

Test e.g. with
```python
import subprocess
from matplotlib.figure import Figure
for fs in [5, 10, 15, 20]:
    Figure(figsize=(fs, fs)).add_subplot().figure.savefig(f"test-{fs}.eps")
    subprocess.run([
        "gs", "-dNOSAFER", "-dNOPAUSE", "-dEPSCrop",
        "-o", f"test-{fs}.png", "-sDEVICE=png16m", f"test-{fs}.eps"])
```

(Noted while troubleshooting failed tests on mplcairo, which does not
perform the centering -- but there were so few tests using eps that the
difference in behavior was entirely hidden by the general mplcairo test
tolerance, until some more tests were added in matplotlib 3.6.)
@anntzer
Copy link
Contributor Author

anntzer commented Sep 27, 2022

I think CI failed because the test conversion cache should be invalidated -- added a commit that drops the caches to check that.

--

Edit: that fixed it indeed; we need to decide how to handle that cache problem.

@QuLogic
Copy link
Member

QuLogic commented Sep 27, 2022

The 1- is there for bumping when necessary.

@anntzer
Copy link
Contributor Author

anntzer commented Sep 28, 2022

Ah, thanks for letting me know. Fixed accordingly.

@QuLogic QuLogic merged commit 6fb17d9 into matplotlib:main Sep 28, 2022
meeseeksmachine pushed a commit to meeseeksmachine/matplotlib that referenced this pull request Sep 28, 2022
QuLogic added a commit that referenced this pull request Sep 29, 2022
…018-on-v3.6.x

Backport PR #24018 on branch v3.6.x (When comparing eps images, run ghostscript with -dEPSCrop.)
@anntzer anntzer deleted the depscrop branch September 29, 2022 05:43
@ksunden ksunden mentioned this pull request Feb 20, 2023
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants