Simplify fill_between paths in SVG and PDF backends#31359
Open
cinocefalia wants to merge 1 commit into
Open
Conversation
cd4b8ed to
0bc881e
Compare
2386e9f to
9b38c23
Compare
Add path simplification for fill_between-generated paths in the PDF and SVG vector backends. Paths tagged with `_fill_between_simplify` are pre-cleaned before encoding, reducing file size for dense datasets. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
9b38c23 to
bc8a682
Compare
Author
|
Regarding my previous comment here, some changes were made Forcing The current approach sidesteps all of that by handling simplification directly in
|
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. its paths are closed polygons (they contain CLOSEPATH codes), which disablesshould_simplifyby design in
Path._update_values. Additionally, filled paths always haveclip=Falseindraw_path, so the existing simplification gate never fired.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
FillBetweenPolyCollection.set_vertstags each generated path with a_fill_between_simplifyattribute.RendererSVG.draw_pathandRendererPDF.draw_path, paths carrying that attribute (and without a hatch) are simplified by checkingrcParams["path.simplify"]andrcParams["path.simplify_threshold"]directly, bypassing the should_simplifyproperty which is alwaysFalse` for closed polygon paths.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 79.7% abd 75.5% for SVG and PDF, respectively. More fragmented cases still showed reductions, though with smaller gains and more mixed timing results.
Implementation notes:
-the change is intentionally narrow in scoppe
-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
Opt-in
Simplification only fires when the user has already set
rcParams["path.simplify"] = TrueandrcParams["path.simplify_threshold"] > 0. This matches how simplification works for line plots in the same backends.The old numbers (99.6-99.7% for interpolate_cross) were from the previous approach with a much larger dataset or different test setup. The real numbers here are more modest but still meaningful (75-80% for the smooth curve case, 25-43% for the fragmented cases).
Test
lib/matplotlib/tests/test_fill_between_simplify.pyverifies that SVG and PDF output size is smaller atsimplify_threshold=1.0than at0.0, for both single and multi-region fill_between scenarios.Tested on 2000-point datasets. Reduction magnitude depends heavily on data density and threshold value - smooth curves (e.g.
interpolate_cross) see near-complete reduction atthreshold=1.0, while fragmentedwheremaskssee smaller gains. The regression tests verify that reduction occurs in both backends across representative scenarios.
AI Disclosure
AI was used to assist with debugging environment issues, crafting the new test and refining the PR description, all the rest being manually tested.
Further explanation on the comments.