Scale expansion is computed in linear data space and then clipped, collapsing log domains
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 554
- Forks
- 30
- Avg merge
- 17h 27m
- Merged PRs (30d)
- 8
Description
This issue came out of work on the Hephaestus writer
Summary
resolve_common_steps expands a continuous scale's input range with expand_numeric_range_selective — plain linear arithmetic on the untransformed values — and only afterwards calls clip_to_transform_domain (src/plot/scale/scale_type/mod.rs:2017-2018, same order in src/plot/scale/types.rs:233). When the padded minimum crosses the transform's valid boundary, the clip replaces it with the boundary's smallest representable value rather than a sensible padded bound. For log that is f64::MIN_POSITIVE, which turns a 3-decade axis into a 311-decade one.
Reproduction
SELECT * FROM (VALUES (1), (10), (100), (1000)) AS t(v)
VISUALISE v AS x, v AS y
DRAW point
SCALE y VIA log
Resolved y scale in the Vega-Lite output:
"scale": { "type": "log", "base": 10, "domain": [2.2250738585072014e-308, 1049.95], "zero": false }
"axis": { "values": [4.999999999999997e-308, 1.999999999999999e-256, 9.999999999999996e-205,
9.999999999999996e-153, 4.999999999999999e-101, 2e-49, 1000.0] }
The data occupies the top ~1% of the axis, and the label expression VL emits for those breaks is 2498 characters of denormal decimal literals.
Expansion is not broken for log in general — it works whenever the padded bound stays positive (body_mass VIA log on ggsql:penguins resolves [2520, 6480], a real 5% pad). The trigger is min − mult·span − add <= 0, i.e. data spanning decades.
Impact
Both writers, differently:
- Vega-Lite — every point crushed against the top of the panel, plus the 2498-char
axis.labelExprabove. - hephaestus — an essentially empty figure: chrome consumes the layout and only the
ytitle survives.
Suggested fix
Expand in transform space: transform the range, apply the multiplicative and additive expansion there, then invert. The padded bound then stays inside the transform's domain by construction, and clip_to_transform_domain becomes a safety net instead of the thing producing the domain.
Contributor guide
No contributing guide indexed for this repository
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.
Research direction
Start in src/plot/scale/scale_type/mod.rs around lines 2017-2018 and the corresponding ordering in src/plot/scale/types.rs:233, following resolve_common_steps, expand_numeric_range_selective, and clip_to_transform_domain. Reproduce the log-scale example and verify that expansion in transform space produces a sensible padded domain for both Vega-Lite and hephaestus, without the extreme axis labels or collapsed plot.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- data-visualization
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100