Problem with domain when using a group

When using a domain on the y axis with grouped data, the x axis labels disappear “below the fold”.

Here’s an example: Problem with domain when using group? / kpm-at-hfi / Observable

Any thoughts?

1 Like

I’m not sure that the issue is directly related to the grouping per se, but rather the fact that you’re now using a barY mark that extends all the way down to y=0, whether you restrict the domain or not.

To get the behavior you want, you might first group the data by hand:

grouped_data = Array.from(d3.group(data, (o) => o.hour).values()).map((a) => ({
  value: d3.mean(a.map((o) => o.value)),
  hour: a[0].hour
}))

and then use the y1/y2 channels of barY to restrict the marks, as well as the domain:

bars_with_y1_y2 = Plot.plot({
  y: {
    domain: [420, 540],
    grid: true
  },
  marks: [Plot.barY(grouped_data, { x: "hour", y1: 420, y2: "value" })]
})

Alternatively, you might simply drop the domain specification to get a more faithful illustration of the data that doesn’t exaggerate the relative differences in the sizes of the groups:

1 Like

Thanks Mark! Yeah in this case we’re looking at a voltage and the straying from 480 rather than a “quantity”, so the exaggeration is actually desirable.

Is there any way to ask barY to not extend all the way down to y=0?

Yes, as Mark showed. If you set y1 and y2 explicitly, rather than just setting y, it won’t extend to 0. Setting only y is equivalent to y1 = 0 and y2 = y.

For a more complete example with the group transform:

Plot.plot({
  y: {
    domain: [440, 520],
    grid: true
  },
  marks: [
    Plot.barY(
      data,
      Plot.groupX(
        { y2: "mean", filter: null },
        { x: "hour", y1: 440, y2: "value" }
      )
    ),
    Plot.ruleY([480], { stroke: "goldenrod", strokeWidth: 2 })
  ]
})
1 Like

Oh my. I see I missed part of @mcmcclur’s answer! So sorry about that! Had I read it properly that was indeed exactly what I needed.

Thanks @mbostock for kindly pointing that out.