observablehq / plot

A concise API for exploratory data visualization implementing a layered grammar of graphics
https://observablehq.com/plot/
ISC License
4.3k stars 175 forks source link

When using `fill: "count"` with the group or bin transform, implicitly set `color: {zero: true}` #2089

Open mbostock opened 3 months ago

mbostock commented 3 months ago

When the group or bin transform is used to generate a fill channel with the count reducer, we want the color scale domain to include zero by default. Otherwise the color scale starts at the lowest value, which can make these low values hard to read, and overemphasize the difference in valid.

Without zero:

untitled - 2024-06-14T122823 384

Plot.plot({
  color: {scheme: "YlGnBu", legend: true},
  marks: [
    Plot.rect(penguins, Plot.groupX({fill: "count"}, {x: "species"}))
  ]
})

With zero:

untitled - 2024-06-14T122833 962

Plot.plot({
  color: {zero: true, scheme: "YlGnBu", legend: true},
  marks: [
    Plot.rect(penguins, Plot.groupX({fill: "count"}, {x: "species"}))
  ]
})
Fil commented 3 months ago

Is this not the case with any scale, not just color? In other words should we not default y to zero: true for

Plot.dot(penguins, Plot.groupX({ y: "count" }, { x: "species" })).plot()
mbostock commented 3 months ago

Good question! Often we don’t think about it because the bar or rect mark requires zero, and the r scale by default includes zero. What do you think? And in any case you should be able to opt-out of this by setting zero: false on the scale.

Fil commented 3 months ago

I think it would make sense to generalize — I've noticed that often, when using a line mark with a bin transform; the y domain then starts at 1 (or whatever the lower count is), and you have to "fix" this by adding a ruleY([0]).