From d1f3a0d541b88eeff2ffd7d04daeb85bf2d8c872 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Tue, 27 Sep 2022 11:48:11 +0200 Subject: [PATCH 1/2] When comparing eps images, run ghostscript with -dEPSCrop. 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.) --- lib/matplotlib/testing/compare.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/testing/compare.py b/lib/matplotlib/testing/compare.py index c2ed8247d93b..4c07c7ad7e09 100644 --- a/lib/matplotlib/testing/compare.py +++ b/lib/matplotlib/testing/compare.py @@ -103,7 +103,7 @@ def __call__(self, orig, dest): if not self._proc: self._proc = subprocess.Popen( [mpl._get_executable_info("gs").executable, - "-dNOSAFER", "-dNOPAUSE", "-sDEVICE=png16m"], + "-dNOSAFER", "-dNOPAUSE", "-dEPSCrop", "-sDEVICE=png16m"], # As far as I can see, ghostscript never outputs to stderr. stdin=subprocess.PIPE, stdout=subprocess.PIPE) try: From 0bd9cf7d80d6bd1608783736bfdda744d72d53fe Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Wed, 28 Sep 2022 11:20:33 +0200 Subject: [PATCH 2/2] Invalidate test caches. --- .github/workflows/tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4e07aee580c2..0c5b7a08ced5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -146,10 +146,10 @@ jobs: ~/.cache/matplotlib !~/.cache/matplotlib/tex.cache !~/.cache/matplotlib/test_cache - key: 1-${{ runner.os }}-py${{ matrix.python-version }}-mpl-${{ github.ref }}-${{ github.sha }} + key: 2-${{ runner.os }}-py${{ matrix.python-version }}-mpl-${{ github.ref }}-${{ github.sha }} restore-keys: | - 1-${{ runner.os }}-py${{ matrix.python-version }}-mpl-${{ github.ref }}- - 1-${{ runner.os }}-py${{ matrix.python-version }}-mpl- + 2-${{ runner.os }}-py${{ matrix.python-version }}-mpl-${{ github.ref }}- + 2-${{ runner.os }}-py${{ matrix.python-version }}-mpl- - name: Install Python dependencies run: |