# Plot: Vertical rect on time axis

**URL:** <https://talk.observablehq.com/t/plot-vertical-rect-on-time-axis/6372>\
**Category:** Help\
**Created:** [March 18, 2022, 8:21pm UTC](https://talk.observablehq.com/t/plot-vertical-rect-on-time-axis/6372 "2022-03-18T20:21:18Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![kadale](https://avatars.discourse-cdn.com/v4/letter/k/8c91f0/32.png) [@kadale](https://talk.observablehq.com/u/kadale)\
**Post date:** [March 18, 2022, 8:21pm UTC](https://talk.observablehq.com/t/plot-vertical-rect-on-time-axis/6372/1 "2022-03-18T20:21:18Z")

</div>

I have plot with a x-axis with `type: utc/time`. I would like to draw vertical rects for each day on the a-axis similar to this reference pic. It is easy with Plot.cell, but since the axis is not ordinal, I cannot use cell.

 ![Screenshot 2022-03-18 at 15-12-03 Static Template](https://canada1.discourse-cdn.com/flex030/uploads/observablehq/original/2X/c/cfe764969a8c71625471d5952a8ab0f70519e6c6.png)

If it was a ordinal axis, I could use Plot.cell with this code.

```auto
range = d3.extent([new Date("2022-01-01"), new Date("2022-04-01")]);
extnt = d3.utcDays(...dextent);

Plot.cell(extnt,
  {
    x: (d) => d,
    // y: "name",
    fill: "#f0dddd50",
    stroke: "white"
  })

```

Similar for saturday and sunday

```auto
sunday = d3.utcSunday.range(new Date("2022-01-01"), new Date("2022-04-01"));
satday = d3.utcSaturday.range(new Date("2022-01-01"), new Date("2022-04-01"));
//Saturday
Plot.cell(satday,
  {
    x: (d) => d,
    fill: "#f0dddd80",
    stroke: "white"
  }),

//Sunday
Plot.cell(sunday,
  {
    x: (d) => d,
    fill: "#f0dddd80",
    stroke: "white"
  })

```

Thanks in advance

---

<div class="post-metadata">

**Author:** ![tophtucker](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/tophtucker/32/4781_2.png) [@tophtucker](https://talk.observablehq.com/u/tophtucker)\
**Post date:** [March 18, 2022, 9:59pm UTC](https://talk.observablehq.com/t/plot-vertical-rect-on-time-axis/6372/2 "2022-03-18T21:59:29Z")

</div>

How’s this? [Plot: vertical rectangles for each day / Toph Tucker / Observable](https://observablehq.com/d/d1bfef68504cd084)

![untitled - 2022-03-18T145921.590](https://canada1.discourse-cdn.com/flex030/uploads/observablehq/original/2X/6/6b610f8f4ddc77394c889fc6454c696572aee423.png)

---

<div class="post-metadata">

**Author:** ![mbostock](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/mbostock/32/9_2.png) [@mbostock](https://talk.observablehq.com/u/mbostock)\
**Post date:** [March 18, 2022, 10:39pm UTC](https://talk.observablehq.com/t/plot-vertical-rect-on-time-axis/6372/3 "2022-03-18T22:39:12Z")

</div>

If _y_ is ordinal and _x_ is temporal (time) then I expect you want Plot.barX (horizontal bars). You can also use the _interval_ option as d3.utcDay if each bar is one day long.

---

<div class="post-metadata">

**Author:** ![kadale](https://avatars.discourse-cdn.com/v4/letter/k/8c91f0/32.png) [@kadale](https://talk.observablehq.com/u/kadale)\
**Post date:** [March 18, 2022, 11:54pm UTC](https://talk.observablehq.com/t/plot-vertical-rect-on-time-axis/6372/4 "2022-03-18T23:54:00Z")

</div>

@tophtucker thanks for the solution. I forgot to include the sample code in my original post - [Vacation Gantt / hashg / Observable](https://observablehq.com/d/9228c1470aabf3a1). I applied your solution. Couple of issues -

1. Top most bar is above the rectangles.
2. The ticks needs to be in middle of rectangles as illustrated in the mockup.

---

<div class="post-metadata">

**Author:** ![kadale](https://avatars.discourse-cdn.com/v4/letter/k/8c91f0/32.png) [@kadale](https://talk.observablehq.com/u/kadale)\
**Post date:** [March 18, 2022, 11:59pm UTC](https://talk.observablehq.com/t/plot-vertical-rect-on-time-axis/6372/5 "2022-03-18T23:59:00Z")

</div>

True, as [suggested by you](https://talk.observablehq.com/t/plot-rulex-not-accepting-new-date/6273/8), I am using Plot.barX to indicate each entry. To enhance the ux, my team wants vertical bars representing each days as depicted in the mockup.

here is my plot with @tophtucker integrated. - [Vacation Gantt / hashg / Observable](https://observablehq.com/d/9228c1470aabf3a1)

---

<div class="post-metadata">

**Author:** ![mbostock](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/mbostock/32/9_2.png) [@mbostock](https://talk.observablehq.com/u/mbostock)\
**Post date:** [March 19, 2022, 12:06am UTC](https://talk.observablehq.com/t/plot-vertical-rect-on-time-axis/6372/6 "2022-03-19T00:06:36Z")

</div>

Here’s my suggestion using barX:

 ![untitled (21)](https://canada1.discourse-cdn.com/flex030/uploads/observablehq/original/2X/0/02d3a266d28ae6fce68cfbe326f813b771ad292c.png)

```nohighlight
Plot.plot({
  x: { axis: "top", round: true },
  y: { padding: 0, grid: true },
  marks: [
    Plot.barX(
      d3.utcDay.range(start, end).filter((d) => d.getUTCDay() < 2),
      { interval: d3.utcDay, fillOpacity: 0.15 }
    ),
    Plot.barX(
      d3.utcDay.range(start, end).filter((d) => d.getUTCDay() >= 2),
      { interval: d3.utcDay, fillOpacity: 0.05 }
    ),
    Plot.barX(data, {
      x1: "startDate",
      x2: "endDate",
      y: "name",
      fill: "name",
      inset: 0.5
    })
  ]
})

```

If you omit the _y_ channel then the barX will span the vertical extent of the chart.

I’m not marking the weekends correctly though… you’ll probably want to fix that. 😅

> **[Plot: vertical rectangles for each day](https://observablehq.com/d/18f85b2380f0edb7)**
>
> Re: kadale in the forum: I have plot with a x-axis with type: utc/time. I would like to draw vertical rects for each day on the x-axis similar to this reference pic. It is easy with Plot.cell, but since the axis is not ordinal, I cannot use cell.

---

<div class="post-metadata">

**Author:** ![Fil](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/fil/32/207_2.png) [@Fil](https://talk.observablehq.com/u/Fil)\
**Post date:** [March 19, 2022, 2:42pm UTC](https://talk.observablehq.com/t/plot-vertical-rect-on-time-axis/6372/7 "2022-03-19T14:42:56Z")

</div>

Could do all the days as one mark with a variable fillOpacity:

```auto
Plot.plot({
  x: { axis: "top", round: true },
  y: { padding: 0, grid: true },
  marks: [
    Plot.barX(d3.utcDay.range(start, end), {
      interval: d3.utcDay,
      fillOpacity: (d) => ((1 + d.getUTCDay()) % 7 < 2 ? 0.15 : 0.05)
    }),
    Plot.barX(data, {
      x1: "startDate",
      x2: "endDate",
      y: "name",
      fill: "name",
      inset: 0.5
    })
  ],
  opacity: { type: "identity" }
})

```

---

<div class="post-metadata">

**Author:** ![kadale](https://avatars.discourse-cdn.com/v4/letter/k/8c91f0/32.png) [@kadale](https://talk.observablehq.com/u/kadale)\
**Post date:** [March 21, 2022, 4:56am UTC](https://talk.observablehq.com/t/plot-vertical-rect-on-time-axis/6372/8 "2022-03-21T04:56:51Z")

</div>

Thanks @mbostock and @Fil for investing time to answer my question, the recommendations are working.

Would it be possible to center the ticks on corresponding bar/rect instead of beginning?

---

<div class="post-metadata">

**Author:** ![Fil](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/fil/32/207_2.png) [@Fil](https://talk.observablehq.com/u/Fil)\
**Post date:** [March 21, 2022, 6:26am UTC](https://talk.observablehq.com/t/plot-vertical-rect-on-time-axis/6372/9 "2022-03-21T06:26:12Z")

</div>

You could try with the following definition for the ticks on the _x_ axis:

```auto
  x: {
    axis: "top",
    round: true,
    ticks: {
      range(a, b) {
        return d3.utcWeek.range(a, b).map((d) => d3.utcHour.offset(d, 12));
      }
    },
    tickFormat: "%b %-d"
  },

```

The _ticks_ will be the same as those generated by d3.utcWeek.range, but shifted by 12 hours. The _tickFormat_ will show the date instead of the default 12AM. (A bit complicated, but dealing with time is always complicated.)

---

<div class="post-metadata">

**Author:** ![kadale](https://avatars.discourse-cdn.com/v4/letter/k/8c91f0/32.png) [@kadale](https://talk.observablehq.com/u/kadale)\
**Post date:** [March 21, 2022, 2:57pm UTC](https://talk.observablehq.com/t/plot-vertical-rect-on-time-axis/6372/10 "2022-03-21T14:57:52Z")

</div>

Awesome it works. Thanks again.

---

<div class="post-metadata">

**Author:** ![mbostock](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/mbostock/32/9_2.png) [@mbostock](https://talk.observablehq.com/u/mbostock)\
**Post date:** [March 21, 2022, 4:04pm UTC](https://talk.observablehq.com/t/plot-vertical-rect-on-time-axis/6372/11 "2022-03-21T16:04:28Z")

</div>

> [@kadale](#):
>
> Would it be possible to center the ticks on corresponding bar/rect instead of beginning?

For what it’s worth, we’re also considering some tweaks to how temporal axes are rendered that would hopefully improve the default appearance.

> <https://github.com/observablehq/plot/issues/460#issuecomment-1003628435>
>
> It would be useful to be able to make axes like this:
> 
> \<br /\>\<br /\>
> 
> !\[image…\](https://user-images.githubusercontent.com/114388/126826951-c60e6b6c-6836-4b40-9868-3d29966bcf4c.png)
> 
> One way would be to support multi-line text labels. 
> 
> Another option would be to allow SVG nodes to be used as ticks rather than coercing the output of \`tickFormat\` to a string, which is the current behavior.
> 
> Here is a notebook which "almost works": https://observablehq.com/d/7de079c962f419f8

---

<div class="post-metadata">

**Author:** ![kadale](https://avatars.discourse-cdn.com/v4/letter/k/8c91f0/32.png) [@kadale](https://talk.observablehq.com/u/kadale)\
**Post date:** [March 21, 2022, 10:35pm UTC](https://talk.observablehq.com/t/plot-vertical-rect-on-time-axis/6372/12 "2022-03-21T22:35:56Z")

</div>

🧐 I’m waiting for it. I need to display year and month in different ticks.
