Simplify fill_between paths in SVG and PDF backends#31359
Draft
cinocefalia wants to merge 2 commits intomatplotlib:mainfrom
Draft
Simplify fill_between paths in SVG and PDF backends#31359cinocefalia wants to merge 2 commits intomatplotlib:mainfrom
cinocefalia wants to merge 2 commits intomatplotlib:mainfrom
Conversation
cd4b8ed to
0bc881e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR summary
Suggestion for closing #22803.
This PR reduces SVG/PDF output size for fill_between by allowing simplification to be applied to FillBetweenPolyCollection paths when path.simplify is enabled.
Why
plot()already benefits from path simplification becauseLine2Dpaths are passed to the backends with the relevant simplification behavior already in place. In contrast,fill_between()produces aFillBetweenPolyCollection, and the resulting collection paths were not consistently reaching the vector backends in a form that allowed the same simplification to happen.In practice, this meant that increasing
path.simplify_thresholdgreatly reduced vector output size for line plots, but often had little or no effect forfill_between().What does this PR change
FillBetweenPolyCollectionmarks its generated paths as simplifiable.should_simplify=True.:in the SVG backend, allows collection path conversion to simplify only paths explicitly marked with should_simplify
in the PDF backend, same it’s done and ensures the collection optimization path is used for marked fill_between paths, so simplification is actually applied
adds regression tests checking that fill_between output becomes smaller for SVG and PDF when path.simplify_threshold is increased
What this approach solves:
For simplifiable fill_between paths, exported SVG/PDF files are reduced substantially. In the strongest benchmarked case (interpolate_cross), output size dropped by about 99.6-99.7% for both SVG and PDF, with corresponding export-time improvements. More fragmented cases still showed reductions, though with smaller gains and more mixed timing results.
Implementation notes:
the change is intentionally narrow in scope
simplification is only enabled for paths explicitly marked as simplifiable, rather than broadening simplification for all collections
the PDF and SVG backends keep their existing behavior for unmarked paths
the tests focus on output-size reduction rather than exact rendering bytes
Benchmark Results:
Top cases
interpolate_cross
SVG:
size: 6242605 -> 18297
reduction: 99.7%
avg time: 0.0860s -> 0.0160s
PDF:
size: 1977991 -> 8846
reduction: 99.6%
avg time: 0.4307s -> 0.0325s
Average cases
where_random
SVG:
size reduction: 33.3%
avg time improvement: about 16%
PDF:
size reduction: 10.6%
avg time improvement: about 4%
Mixed bag case
multi_regions
SVG:
size reduction: 23.7%
avg time improvement: very small, about 4%
PDF:
size reduction: 6.2%
but avg time got worse after multiple runs
27.6s -> 45.8s
minimum time also worse
Regression test has been added in
lib/matplotlib/tests/test_fill_between_simplify.py.AI Disclosure
AI was used to assist with debugging environment issues and refining the PR description, all the rest being manually tested.
The benchmarks results didn’t change much overall compared to my previous approach, but some changes had to be done. I believe this is the cleaner version as of now
#22803 (comment)