Performance: line PNG export misses the 10× Matplotlib target (7.18× in release audit)
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Domain
- data-visualization, performance, testing
Research direction
Start with benchmarks/bench_pyplot_vs_matplotlib.py and spec/benchmarks/methodology.md; first reproduce the line result on a controlled runner using the standard-profile command in the issue, recording raw samples, environment, dimensions, and tier. Profile build, rasterization, and PNG encoding separately, then compare smoke, standard, and huge profiles and their output sizes. Done means meeting the 10× line target or revising the specification with reproducible evidence, while preserving image correctness, labels, dimensions, and tier disclosure.
Written by the indexing model from the issue text.
Description
The matched-output release benchmark found a line export gap against the existing per-family 10× Matplotlib/Agg goal in the benchmark methodology.
| Workload | XY total median | Matplotlib total median | Speedup | XY tier |
|---|---|---|---|---|
| 20,000 samples | 11.46 ms | 82.24 ms | 7.18× | decimated |
Both outputs are nonblank 1800×840 PNGs. The metric is figure construction through a completed compressed PNG, excluding imports, data generation and warm-up. XY uses the disclosed M4-decimated tier for this row; Matplotlib/Agg paints every sample. Preserve extrema and disclose the tier in every comparison.
These are diagnostic results from three repetitions on a shared workstation, with one warm-up, recorded during the 2026-11-05 release audit. Confirm the gap on a controlled runner before selecting an optimization. This does not establish a regression from v0.0.8.
Reproduce
Audited source: 5e58b12c0a1b89a58c4555af370204ef1ed0515e plus local release-validation fixes. Environment: Linux x86_64, 12 logical CPUs, CPython 3.14.6, NumPy 2.5.1, Matplotlib 3.11.0, native XY core, Rust 1.96.0.
Harness prerequisite: the audited upstream bench_pyplot_vs_matplotlib.py omits export DPI in _xy_render. Set its save call to the following before measuring, matching the Matplotlib adapter:
fig.savefig(out, format="png", dpi=EXPORT_DPI)
Both adapters build at 100 DPI and export at 200 DPI. Without that correction, the harness fails its dimension check before producing a valid comparison. The correction and output-size regression test are prepared locally on farhan/release-validation, but have not landed upstream.
cargo build --release
uv sync --extra matplotlib --group dev
uv pip install 'matplotlib==3.11.0'
MPLBACKEND=Agg uv run --no-sync python benchmarks/bench_pyplot_vs_matplotlib.py \
--profile smoke --reps 3 --warmups 1 \
--json /tmp/pyplot-smoke.json
The harness runs all six families; inspect the line row. For confirmation and the existing standard target gate:
MPLBACKEND=Agg uv run --no-sync python benchmarks/bench_pyplot_vs_matplotlib.py \
--profile standard --reps 21 --warmups 3 \
--target-speedup 10 --require-target \
--json /tmp/pyplot-standard.json
--require-target gates every family, so a failure in another family does not by itself establish this issue's outcome.
Raw observations
[
{
"library": "xy.pyplot",
"total_samples_ms": [
9.282415,
12.12937,
11.45841
],
"build_median_ms": 0.492518,
"render_median_ms": 10.854134,
"total_median_ms": 11.45841,
"total_p95_ms": 12.12937,
"png_bytes": 150193
},
{
"library": "matplotlib",
"total_samples_ms": [
80.364108,
82.328557,
82.23864
],
"build_median_ms": 3.908362,
"render_median_ms": 78.330278,
"total_median_ms": 82.23864,
"total_p95_ms": 82.328557,
"png_bytes": 92530
}
]
Acceptance
- Reproduce on a controlled runner and record environment, exact commit, raw samples, output dimensions and tier decisions.
- Profile build, rasterization and PNG encoding separately; optimize the measured bottleneck.
- Meet the existing standard-profile 10× total-time target for line, or explicitly revise the specification with reproducible evidence explaining why the target is not met.
- Retain image correctness, labels and dimensions; do not achieve the target by silently reducing visual quality or dropping data.
- Record smoke, standard and huge profile results and output sizes, and add a meaningful regression benchmark.
- Update benchmark evidence and specifications with the resulting behavior.
The local audit report and complete raw comparison are prepared under spec/process/release-validation/2026-11-05/; they are currently uncommitted. The observations above are included here so this issue is reproducible without access to that worktree.
- Dominant language
- Python
- Stars
- 1.9k
- Forks
- 79
- Avg merge
- 1d 39m
- Merged PRs (30d)
- 22
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from reflex-dev/xy
-
Skip finite/log visibility scans when zone maps already prove all-finite on linear axesMay be free again A pull request for this issue was closed without being merged. Openneeds investigate performance
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
reflex-dev/xy#169 ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 57/100
reflex-dev/xy#556 ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 20/100
reflex-dev/xy#552 ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 30/100
reflex-dev/xy#551 ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
reflex-dev/xy#523 ·
Maintainers usually reply within 1 day
Similar issues
-
release
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
MichaelYcJo/SpecSeal#1535 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
valentinfrlch/ha-llmvision#769 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 1/5 Under an hour Newbie friendliness 75/100
daniel-ospina/tortoise#11937 · 1 comment ·
Maintainers usually reply within 1 day
-
good first issue help wanted python up-for-grabs
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
andrewsiah/agentswarm-data-tasks#238 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
cadence-workflow/cadence-ai-samples#175 ·
Maintainers usually reply within 1 day