Skip to content

Hatching in EPS figures doesn't show up in Preview on MacOS X with Matplotlib 2.0 #8289

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

Closed
astrofrog opened this issue Mar 14, 2017 · 20 comments

Comments

@astrofrog
Copy link
Contributor

Patches that have a hatch pattern in EPS plots don't show the hatch pattern when opened in Preview on MacOS X. This may be a Preview bug rather than a Matplotlib bug, but I wanted to check whether anything can be done on the Matplotlib side to avoid this (since the likelihood Apple will care about this issue is minimal). This was not a problem with Matplotlib 1.5, only with 2.0, so in that sense this is a regression.

To reproduce this:

from matplotlib import pyplot as plt
from matplotlib.patches import Ellipse

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ell = Ellipse((0.5, 0.5), 0.3, 0.4, 30, hatch='/', facecolor='none', edgecolor='black')
ax.add_patch(ell)
fig.savefig('test.eps')

PNG:

test

EPS, as viewed in Preview on MacOS X:

screen shot 2017-03-14 at 08 52 50

The above is with Matplotlib 2.0. With 1.5, Preview correctly shows the hatch pattern:

screen shot 2017-03-14 at 09 01 54

I'm using MacOS X 10.11.6

@afvincent
Copy link
Contributor

Just to be sure: the hatches do actually exist in the EPS file (e.g. the issue is only with the preview)? I ran your MWE on Linux and Python 2 with Matplotlib 1.5.1 and 2.0: in Evince I can see hatches in both of them. However the hatches do not look exactly identical between both records, which I guess is due to #7421 (ping @QuLogic)

@astrofrog
Copy link
Contributor Author

@afvincent - yes, I think they do, I can see the hatches if I open the file with ghostscript

@tacaswell
Copy link
Member

what is the diff between the two files?

@QuLogic
Copy link
Member

QuLogic commented Mar 14, 2017

The changes in the individual commits of #7421 are fairly self-contained; it should be possible to try reverting them one at a time to see if they have any effect. At a guess, I'd say this commit and Preview has some trouble with the setpattern shortcut. You can revert the very last block in that patch to test out that theory.

@tacaswell
Copy link
Member

https://github.com/matplotlib/matplotlib/pull/7421/files#diff-b465967f537465fec4960b152fa49cffR903 is likely the specific change at fault.

https://www.adobe.com/products/postscript/pdfs/PLRM.pdf has the documentation on this and

setpattern is the normal method for selecting patterns; in practice, it is rarely necessary to set the color space and color value separately

pg 264

@tacaswell tacaswell added this to the 2.0.1 (next bug fix release) milestone Mar 14, 2017
@afvincent
Copy link
Contributor

Sorry, unexpected workload at day-job last night. So here are the differences that I can observe both in Evince and GS between Matplotlib 1.5.1 and 2.0:
eps_and_hatches_differences_between_1 5 1_and_2 0
The main one is that the hatches do not have a constant line width with 2.0.

@WeatherGod
Copy link
Member

WeatherGod commented Mar 15, 2017 via email

@afvincent
Copy link
Contributor

@WeatherGod I think the problem is not about the hatching style but more about how hatching is defined when saving in postscript and how it affects the rendering in Preview, Evince, GS, etc. as @QuLogic and @tacaswell have suggested. For example, when the hatches density is doubled ('//' instead of '/'), the not very aesthetic bold segments on some of the hatches are still there in EPS produced by 2.0, while the line width stays smooth and constant with 1.5(.1):
eps_and_hatches_differences_between_1 5 1_and_2 0_bis

@tacaswell
Copy link
Member

When I said diff I meant the text diff. I don't think the hatch changing width is real, that looks like issues with the renderer. Do they move around if you pan / zoom / resize the window?

@afvincent
Copy link
Contributor

The answer seems to be no with 1.5.1 (left panels) and yes with 2.0 (right panels):
eps_and_hatches_differences_between_1 5 1_and_2 0_zoom_impact
The three level of zoom are 0.707, 1.000 and 2.000. With the EPS generated by Matplotlib 2.0, one can observe “glitches” for the two levels of zoom that are different from 1.

I agree that is is likely to be an issue with how the GS/Evince/Preview do the rendering.

I put the EPS files and a diff there

@QuLogic QuLogic modified the milestones: 2.0.1 (next bug fix release), 2.0.2 (next bug fix release) May 3, 2017
@tacaswell tacaswell modified the milestones: 2.1.1 (next bug fix release), 2.2 (next feature release) Oct 9, 2017
@master-bit
Copy link

Hi, I've got a similar problem. I generate a hatched part in a figure with fill_between. Figure is saved to eps. It shows in Linux Document viewer and Okular.
If I now incorparate the file into a pdf document via latex, the hatching is only visible in ocular, not in the document viewer. Also not printed.

bildschirmfoto vom 2017-11-22 12 04 26
first picture: The file opened in document viewer individually as eps (left) and in the pdf (right). Hatching not in the pdf

bildschirmfoto vom 2017-11-22 12 05 06
second picture: The file opened in okular individually as eps (left) and in the pdf (right). Hatching visible

@tacaswell tacaswell added backend: pdf backend: ps Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. labels Nov 23, 2017
@tacaswell tacaswell modified the milestones: v2.2, v3.0 Feb 4, 2018
@tacaswell
Copy link
Member

Punting to 3.0, this is not going to get fixed in the next few days.

@tacaswell tacaswell modified the milestones: v3.0, v3.1 Aug 27, 2018
@tacaswell tacaswell removed the Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. label Aug 27, 2018
@tacaswell
Copy link
Member

I suspect that the resolution here is going to involve someone fully understanding the eps/pdf spec and then sorting out which of the viewers is buggy....

This reminds me of the clipping issues we hand with librsvg for a while (we were outputting svg that complied with the spec, but rsvg did not render them correctly).

@mryodo
Copy link

mryodo commented Feb 7, 2019

Guys, has this issue been resolved? It seems like I'm having this problem on the latest module version. Or maybe any workaround?

@mkvoya
Copy link
Contributor

mkvoya commented Feb 7, 2019

@mryodo, I got the behaviour correct by inserting gsave and grestore in backend_ps.py. I don't known whether this will incur other problems, but at least you could give it a try.

I don't know how to present my modification here, so I just attach my git diff below. Hope it helps.

diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py
index 62edbb919..c8877e2ab 100644
--- a/lib/matplotlib/backends/backend_ps.py
+++ b/lib/matplotlib/backends/backend_ps.py
@@ -311,7 +311,9 @@ class RendererPS(RendererBase):
             self._convert_path(Path.hatch(hatch), Affine2D().scale(sidelen),
                                simplify=False))
         self._pswriter.write("""\
+        gsave
         fill
+        grestore
         stroke
      } bind
    >>

@anntzer
Copy link
Contributor

anntzer commented Feb 7, 2019

https://stackoverflow.com/questions/6614207/how-to-export-non-blurry-eps-images for another case of Preview apparently not rendering postscript correctly.

@mryodo
Copy link

mryodo commented Feb 7, 2019

@mksegv Thanx! Works perfectly!

@mryodo, I got the behaviour correct by inserting gsave and grestore in backend_ps.py. I don't known whether this will incur other problems, but at least you could give it a try.

I don't know how to present my modification here, so I just attach my git diff below. Hope it helps.

diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py
index 62edbb919..c8877e2ab 100644
--- a/lib/matplotlib/backends/backend_ps.py
+++ b/lib/matplotlib/backends/backend_ps.py
@@ -311,7 +311,9 @@ class RendererPS(RendererBase):
             self._convert_path(Path.hatch(hatch), Affine2D().scale(sidelen),
                                simplify=False))
         self._pswriter.write("""\
+        gsave
         fill
+        grestore
         stroke
      } bind
    >>

@tacaswell tacaswell modified the milestones: v3.1.0, v3.2.0 Mar 18, 2019
@czeni
Copy link

czeni commented Aug 15, 2019

Issue is still present in Matplotlib 3.1.1, but the posted fix worked like a charm! Thanks.

@mryodo, I got the behaviour correct by inserting gsave and grestore in backend_ps.py. I don't known whether this will incur other problems, but at least you could give it a try.

I don't know how to present my modification here, so I just attach my git diff below. Hope it helps.

diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py
index 62edbb919..c8877e2ab 100644
--- a/lib/matplotlib/backends/backend_ps.py
+++ b/lib/matplotlib/backends/backend_ps.py
@@ -311,7 +311,9 @@ class RendererPS(RendererBase):
             self._convert_path(Path.hatch(hatch), Affine2D().scale(sidelen),
                                simplify=False))
         self._pswriter.write("""\
+        gsave
         fill
+        grestore
         stroke
      } bind
    >>

@jklymak
Copy link
Member

jklymak commented Aug 15, 2019

Does anyone want to open a PR for that change?

@QuLogic
Copy link
Member

QuLogic commented Jul 24, 2020

This should have been fixed by #15064.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests