Skip to content

Circular hatching patterns contain too many path segments #4122

Closed as not planned

Description

@jowr

The produced PGF documents litarally explode in file size as soon as you start using dotted hatching patterns. Some of my graphs cannot be compiled by pdflatex anymore...
A simple plot like this one:

import matplotlib.pyplot as plt
fig = plt.gcf()
ax = fig.add_subplot(111)
ax.bar(0.85, 5, 0.3, color="lightgrey", hatch="////")
ax.set_xlim([0,3])
ax.set_ylim([0,10])
plt.tight_layout()
fig.savefig("pgfhatch_1.pgf")
fig.savefig("pgfhatch_1.pdf")
ax.bar(1.85, 7, 0.3, color="lightgrey", hatch="....")
fig.savefig("pgfhatch_2.pgf")
fig.savefig("pgfhatch_2.pdf")
plt.close()

produces files of very different sizes

-rw-r--r-- 1 jorrit jorrit 6.9K Feb 18 09:29 pgfhatch_1.pdf
-rw-r--r-- 1 jorrit jorrit  27K Feb 18 09:29 pgfhatch_1.pgf
-rw-r--r-- 1 jorrit jorrit  55K Feb 18 09:30 pgfhatch_2.pdf
-rw-r--r-- 1 jorrit jorrit 668K Feb 18 09:29 pgfhatch_2.pgf

However, the result is OK, but it takes ages to compile with pdflatex (if it succeeds).

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tabular}{cc}
\input{pgfhatch_1.pgf} & \input{pgfhatch_2.pgf} \\
\includegraphics{pgfhatch_1.pdf} & \includegraphics{pgfhatch_2.pdf}
\end{tabular}
\end{document} 

horner

Could it help to make real dots instead of circles?

Activity

  1. tacaswell commented on Feb 18, 2015

    @tacaswell
    Member

    cc @pwuertz Can you mile stone this appropriately?

  2. pwuertz commented on Feb 18, 2015

    @pwuertz
    Contributor

    Well, the path matplotlib provides for the second hatch pattern contains a whopping number of 6130 path segments. This naturally increases the number of pgf commands which latex cannot handle anymore at some point.

    backend_svg suffers from the same problem, but backend_pdf doesn't seem to use the hatch path at all and simply interprets the hatch name. The naming scheme appears to be native to PDF, but I don't know much about this format.

    So it looks like the pattern generated for all the non-PDF backends isn't very efficient when you shrink the elements / increase the pattern's density.

  3. pwuertz commented on Feb 18, 2015

    @pwuertz
    Contributor

    Well, actually its only the circular patterns that seem to be overly complicated. Even the basic patterns contain 500-1000 segments.

  4. added this to the milestone on Feb 18, 2015
  5. changed the title [-]PGF backend produces huge files for dotted hatching pattern[/-] [+]Circular hatching patterns contain too many path segments[/+] on Feb 18, 2015
  6. pwuertz commented on Feb 18, 2015

    @pwuertz
    Contributor

    Does anybody know some details about how/where these patterns are created within matplotlib? Since cubic splines are supported in Path, a simple circle shouldn't require more than 4 path segments.

  7. mdboom commented on Feb 18, 2015

    @mdboom
    Member

    The hatches are generated in hatch.py, but many of them use lower-level paths from path.py.

    Since the circle path is often used quite large in matplotlib, it actually uses an 8-cubic-spline approximation, not a 4-cubic-spline one, because the error was noticable on high-resolution plots, particularly if only part of the circle was shown. For hatching, that level of accuracy isn't necessary, of course, so added a 4-spline approximation for that purpose would be fine.

    But that doesn't explain why we see 500-1000 segments. Perhaps a bezier spline to line segment conversion is happening somewhere along the way?

  8. pwuertz commented on Feb 18, 2015

    @pwuertz
    Contributor

    Ok, so for the "o" pattern I'm seeing circle instances using the 8 segment approximation you were mentioning. For each dot there are two circles, a smaller and a larger one. The basic hatch pattern contains about 50 dots, which amounts to 800 segments. So the problem isn't really the number of segments per circle, it's the amount of circles.

  9. mdboom commented on Feb 18, 2015

    @mdboom
    Member

    I see -- in that case, the solution may be to reduce the size of the hatch pattern so it contains fewer circles. Unfortunately, it's currently hard-coded, i.e. all of the backends assume the hatch pattern is a 1x1inch square. So I think fixing that will require updating all of the backends.

  10. jowr commented on Feb 18, 2015

    @jowr
    ContributorAuthor

    Thank you for the fast responses and good luck with fixing this. I wasn't aware that it was such a general issue.

  11. pwuertz commented on Feb 18, 2015

    @pwuertz
    Contributor

    Oh, I am mistaken. Also the PDF backend uses the hatch path from matplotlib, it just uses a different method for retrieving it. However, at least on my system the hatch pattern appears to be rasterized in the PDF output, which explains the much smaller file size compared to the fully vectorized PGF or PGF->PDF output.

    Scaling of the pattern density within the backend sounds like a good approach. But yes, every backend would need to implement this individually, which probably won't happen anytime soon. I don't see a good workaround, other than to avoid using non-trivial high-density patterns for now.

    Thanks for the quick reply @mdboom

  12. jowr commented on Feb 18, 2015

    @jowr
    ContributorAuthor

    I am not sure, but doesn't this #4108 indicate that the PDF backend does not render the hatch pattern?

  13. pwuertz commented on Feb 18, 2015

    @pwuertz
    Contributor

    @jowr You are right, on my Ubuntu system it was the default PDF viewer that rasterized the hatch pattern before applying it, the document is fully vectorized. So it's just PDF being able to store the pattern more efficiently than a million lines of latex code ;)

  14. mdboom commented on Feb 19, 2015

    @mdboom
    Member

    Interesting... PDF is zlib compressing the path data, so that's probably a lot better than PGF wrt file size. SVG is also pretty bad, but still about half the size of PGF. PGF is just really verbose unfortunately, and probably really works the TeX parser, whereas SVG and PDF both have much simpler languages to represent paths.

  15. modified the milestones: , on Mar 21, 2016
  16. added
    Difficulty: Hardhttps://matplotlib.org/devdocs/devel/contribute.html#good-first-issues
    on Mar 21, 2016
  17. modified the milestones: , on Oct 3, 2017
  18. github-actions commented on Jun 5, 2023

    @github-actions

    This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

  19. added
    status: closed as inactiveIssues closed by the "Stale" Github Action. Please comment on any you think should still be open.
    on Jul 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Difficulty: Hardhttps://matplotlib.org/devdocs/devel/contribute.html#good-first-issuesstatus: closed as inactiveIssues closed by the "Stale" Github Action. Please comment on any you think should still be open.status: inactiveMarked by the “Stale” Github Actiontopic: hatch

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions