🏠 back to Observable

Calendar-aligned axis ticks with Plot.cell

I am using Plot.cell to make a 2D plot in which the x-axis represents day of year and the y-axis represents time of day.

I’d like to add ticks along the x-axis showing Jan 1, Feb 1, Mar 1, etc. How can I achieve this?

Notebook here, but warning: it requires a lot of RAM. Herring Data Visualization / Ryan Govostes / Observable

Other recommendations welcome — perhaps using Plot.cell is not the most performant or appropriate way to achieve this?

You could do something like this:

XAxisFormat = {
  const EndDate = d3.utcYear.offset(d3.utcYear(StartDate), 1);
  return {
    domain: d3.utcDay.range(StartDate, EndDate),
    ticks: d3.utcMonth.range(StartDate, EndDate),
    tickFormat: "%b",
    round: false
  }
}

Another way of approaching this would be to use Plot.bin and Plot.rect. Then you can do you aggregation within the visualization itself, where x is a temporal axis (not ordinal) and y is a quantitative axis (also not ordinal, representing minutes since midnight):

Plot.plot({   
  round: true,
  y: {
    tickFormat: d => d3.utcFormat("%-I %p")(d3.utcMinute.offset(0, d)),
    ticks: d3.range(25).map(h => h * 60),
    reverse: true
  },
  color: {
    scheme: "YlGnBu"
  },
  marks: [
    Plot.rect(
      Data,
      Plot.bin({
        fill: "count"
      }, {
        x: {
          value: ([date]) => date,
          thresholds: d3.utcDay
        },
        y: {
          value: ([date]) => date.getUTCHours() * 60 + date.getUTCMinutes(),
          thresholds: d3.range(1, 24).map(h => h * 60)
        },
        filter: d => d[thresh + 1] >= DetectionThreshold,
        inset: 0
      })
    )
  ]
})

This still takes a few seconds to bin the 5.6M records… I suspect that could be optimized, though. I didn’t investigate yet to see whether there is obvious room for improvement. But at least it shouldn’t be slow from the rendering side; you can adjust the thresholds to make larger bins.