plot icon indicating copy to clipboard operation
plot copied to clipboard

Tick values in quantile legend don't get rounded

Open mootari opened this issue 5 months ago • 3 comments

It appears that the tick values in a quantile legend don't get rounded. Example:

Plot.barX([0,1,2,3], {fill: d => d}).plot({color: {type: "quantile", legend: true}})
Plot.barX([0,1,2,3,4,5,6], {fill: d => d}).plot({color: {type: "quantile", legend: true, n: 7}})
Image

mootari avatar Sep 24 '25 10:09 mootari

Good catch, even though your examples are a bit contrived (with more ticks than data points), the problem also arises when you use quantiles on a series of numbers with many digits after the comma.

Image

For me the correct option might not be to round the values in the legend, but instead to modify the scale so that it identifies the "simplest" number that separates the values above and the values below each block.

For example if the quantile falls between 1.233333 (excluded) and 1.36666667 (included), 1.3 would be the best separator. Note that rounding (to 1.4, 1.37… or 1.36667) would be wrong since it would go over 1.36666667—we can only round down, and not too much, depending on the numbers that are in the previous bucket.

I don't think this can be implemented with a tickFormat option, since it needs to read two consecutive values at once from the original domain.

See https://observablehq.com/@fil/clean-quantiles for a prototype

(and congrats on this issue's number)

Fil avatar Sep 24 '25 14:09 Fil

I think just using number.toLocaleString would be sufficient to fix this. The alternative of having cleaner quantiles sounds interesting too. Should that be opt-in, or do you think it would just work good enough for every case?

mbostock avatar Sep 24 '25 15:09 mbostock

Yes number.toLocaleString("en-US") is much better than the status quo for the examples above:


however it's not generic in the sense that it won't cover smallish domains (like [0, 1e-7, 1e-4]):

my prototype instead gives:

Should we try and create this in D3? Should it be a new option for quantile scales? (I think it'd be fine for Plot to select that option by default, but it seems too much of a change for d3.quantileScale?)

Fil avatar Sep 24 '25 15:09 Fil