Search code examples
rdataframelubridate

Why does floor_date prevent geom_rect() to draw?


I'd like to know why these two code snippets won't produce the same results. Why are these two charts different ?

library("ggplot2")
library("lubridate")

# This will draw a line only
a <- data.frame(
    day=c(floor_date(ymd_hms("2021/12/20 10:00:00"), unit="days"),
          floor_date(ymd_hms("2021/12/21 11:11:11"), unit="days")),
    start=c(10,20),
    end=c(50,60))
ggplot(a) + geom_rect(aes(xmin=day,xmax=day+1,ymin=start, ymax=end)) + geom_line(aes(x=day,y=start))

# This will draw a line *and* a rectangle
a <- data.frame(
    day=c(ymd("2021/12/20"),
          ymd("2021/12/21")),
    start=c(10,20),
    end=c(50,60))
ggplot(a) + geom_rect(aes(xmin=day,xmax=day+1,ymin=start, ymax=end)) + geom_line(aes(x=day,y=start))

Edit: replaced day+0.5 with day+1 to avoid misleading to a rounding issue.


Solution

  • The class of day is POSIXct for the first and Date for the second example. The + operator does things differently:

    library("lubridate")
    #> 
    #> Attaching package: 'lubridate'
    #> The following objects are masked from 'package:base':
    #> 
    #>     date, intersect, setdiff, union
    
    floor_date(ymd_hms("2021/12/20 10:00:00"), unit="days") + 0.5
    #> [1] "2021-12-20 00:00:00 UTC"
    ymd("2021/12/21") + 0.5
    #> [1] "2021-12-21"
    

    Created on 2021-09-09 by the reprex package (v2.0.1)

    The first example will lead into bars of width 0.