Search code examples
rdatetimeggplot2annotations

R: ggplot not showing geom_segment over datetime


I want to plot a geom_segment over datetime, like a simple Gantt chart. I plot a geom_segment from a data frame (df) and then one geom_segment within ggplot. The problem is, when the x-scale limit is overlapping with the geom_segment it vanishes. But only the geom_segment created from the data frame. The other one is working correctly. Here is the code:

    output$TA_2 <- renderPlot({

    df <- data.frame("Start" = c("2019-08-13"),
                   "End" = c("2019-08-15"),
                   "y" = c(1))

    df$Start <- as.POSIXct(2019-01-01, origin = df$Start)
    df$End <- as.POSIXct(2019-01-01, origin = df$End)

    ggplot(df, aes(x = Start, y = y)) +
      geom_segment(aes(xend = End, yend = y), size=4) +
      theme_bw() +
      scale_y_continuous(limits=c(0,3)) +
      scale_x_datetime(date_breaks = "24 hour", labels = date_format("%d.%m - %H:%M"), 
                     minor_breaks = "24 hour", expand=c(0,0),
                     limits = c(
                       as.POSIXct(2019-01-01, origin = "2019-08-14"),
                       as.POSIXct(2019-01-01, origin = "2019-08-16")
                     )) +
      geom_segment(x = as.POSIXct(2019-01-01, origin = "2019-08-13"), 
                 xend = as.POSIXct(2019-01-01, origin = "2019-08-15"), 
                 y = 2, yend = 2, size=1)
})

If the x-scale limit

limits = c(
as.POSIXct(2019-01-01, origin = "2019-08-14"),
...

is adjusted to e.g.

limits = c(
as.POSIXct(2019-01-01, origin = "2019-08-10"),
...

both segments appear.

What do I have to do, that the segment created from the data frame is working also with overlapping?


Solution

  • Instead of setting the limits in scale_x_datetime which cuts off your df, you can use coord_cartesian which just zooms in and leaves the segment in.

    ggplot(df, aes(x = Start, y = y)) +
      geom_segment(aes(xend = End, yend = y), size=4) +
      theme_bw() +
      scale_y_continuous(limits=c(0,3)) +
      scale_x_datetime(date_breaks = "24 hour", labels = date_format("%d.%m - %H:%M"), 
                       minor_breaks = "24 hour", expand=c(0,0)) +
      geom_segment(x = as.POSIXct(2019-01-01, origin = "2019-08-13"), 
                   xend = as.POSIXct(2019-01-01, origin = "2019-08-15"), 
                   y = 2, yend = 2, size=1) +
      coord_cartesian(xlim = c(
        as.POSIXct(2019-01-01, origin = "2019-08-14"),
        as.POSIXct(2019-01-01, origin = "2019-08-16")
      ))