Skip to content

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

Closed

Description

@astrofrog

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

Activity

  1. afvincent commented on Mar 14, 2017

    @afvincent
    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)

  2. astrofrog commented on Mar 14, 2017

    @astrofrog
    ContributorAuthor

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

  3. tacaswell commented on Mar 14, 2017

    @tacaswell
    Member

    what is the diff between the two files?

  4. QuLogic commented on Mar 14, 2017

    @QuLogic
    Member

    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.

  5. tacaswell commented on Mar 14, 2017

    @tacaswell
    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

  6. added this to the milestone on Mar 14, 2017
  7. afvincent commented on Mar 15, 2017

    @afvincent
    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.

  8. WeatherGod commented on Mar 15, 2017

    @WeatherGod
    Member
  9. afvincent commented on Mar 16, 2017

    @afvincent
    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

  10. tacaswell commented on Mar 16, 2017

    @tacaswell
    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?

  11. afvincent commented on Mar 16, 2017

    @afvincent
    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

  12. modified the milestones: , on May 3, 2017
  13. 13 remaining items

  14. mryodo commented on Feb 7, 2019

    @mryodo

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

  15. mkvoya commented on Feb 7, 2019

    @mkvoya
    Contributor

    @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
        >>
    
  16. anntzer commented on Feb 7, 2019

    @anntzer
    Contributor

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

  17. mryodo commented on Feb 7, 2019

    @mryodo

    @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
        >>
    
  18. modified the milestones: v3.1.0, v3.2.0 on Mar 18, 2019
  19. czeni commented on Aug 15, 2019

    @czeni

    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
        >>
    
  20. jklymak commented on Aug 15, 2019

    @jklymak
    Member

    Does anyone want to open a PR for that change?

  21. QuLogic commented on Jul 24, 2020

    @QuLogic
    Member

    This should have been fixed by #15064.

  22. modified the milestones: needs sorting, v3.2.0 on Jul 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions