Skip to content

Simplify fill_between paths in SVG and PDF backends#31359

Draft
cinocefalia wants to merge 2 commits intomatplotlib:mainfrom
cinocefalia:fillbetween-simplify-clean
Draft

Simplify fill_between paths in SVG and PDF backends#31359
cinocefalia wants to merge 2 commits intomatplotlib:mainfrom
cinocefalia:fillbetween-simplify-clean

Conversation

@cinocefalia
Copy link

@cinocefalia cinocefalia commented Mar 24, 2026

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 because Line2D paths are passed to the backends with the relevant simplification behavior already in place. In contrast, fill_between() produces a FillBetweenPolyCollection, 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_threshold greatly reduced vector output size for line plots, but often had little or no effect for fill_between().

What does this PR change

  • FillBetweenPolyCollection marks its generated paths as simplifiable.
  • PDF/SVG simplification is applied only to paths explicitly marked with 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
  • The PDF collection optimization logic is adjusted so simplifiable collection paths are not blocked from reaching the simplification path in common single-use cases.

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)

  • "closes #0000" is in the body of the PR description to link the related issue
  • new and changed code is tested
  • [N/A] Plotting related features are demonstrated
  • [N/A ] New Features and API Changes are noted
  • [N/A] Documentation complies with general and docstring guidelines

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant