Annotating in ggplots with POSIXct class data

Solution for Annotating in ggplots with POSIXct class data
is Given Below:

I’m looking for help annotating or creating a legend for 2 subsets of data from the same df on a geom-line plot. The difficulties appear to be because I have POSIXct data on my X-axis. I found a question about the same issue but no clear answer and possibly a bug yet to be addressed – How to use ggplot2’s annotate with dates in x-axis?

My plot summarises the median time spent by patients (left.true) in an hospital ward across according to the time of arrival onto the ward using data collected over several weeks. The time spent differs according to time of arrival (start.time) and the area of the ward they arrive into (INITIAL.AREA) so needs to be visualised as two separate lines but plotted together across time for client understanding – hence two geom_line subsets.

Apologies for the inelegant code, but creating the plot crequires time of arrival from one of 2 vectors with a preference for the variable Add.Time unless it is not recorded (i.e., NA), at which point it sets start.time according to an alternative variable.

los.plot <- ggplot() +
  geom_line(data = los2 %>%
              filter(INITIAL.AREA == "AMU") %>%
              mutate(start.time = case_when(
                !is.na(Adm.Time) ~ Adm.Time,
                is.na(Adm.Time) ~ Ward.Start.Time..in.Bed.)) %>%
              select(start.time, left.true) %>%
              group_by(start.time) %>%
              summarise(median = median(left.true)),
            aes(x=start.time, y=(median/60)), color="grey30") +
  geom_line(data = los2 %>%
              filter(INITIAL.AREA == "AAA") %>%
              mutate(start.time = case_when(
                !is.na(Adm.Time) ~ Adm.Time,
                is.na(Adm.Time) ~ Ward.Start.Time..in.Bed.)) %>%
              select(start.time, left.true) %>%
              group_by(start.time) %>%
              summarise(median = median(left.true)),
            aes(x=start.time, y=(median / 60)), color="magenta") +
  labs(title = "Median LoS according to initial area of care",
       subtitle = "(Data from October 2019: n=1409)", #NAs removed
       caption = c("AEC patients","AMU Bedded patients"),
       x = "Time of arrival onto unit", 
       y = "Median LoS (hours)") +
  theme(plot.caption = element_text(face = "bold", 
                                    color = c('magenta', 'grey30'),
                                    hjust=c(1, 0))) +
  scale_x_datetime(breaks = time.breaks, 
                   labels = c("00:00", "02:00", "04:00", "06:00", '08:00', 
                              '10:00', '12:00','14:00', '16:00', 
                              '18:00', '20:00', '22:00', '24:00'))

Trying to use annotate with

los.plot + annotate("text", x =03:00:00, y=1, label = "AEC patients",color="magenta")                 

leads to

Error: Invalid input: time_trans works with objects of class POSIXct only

I’m assuming this is because the x-axis position argument is incompatible with a POSIXct class. I can’t seem to find a way around this.

So far my only solution has been labs(captions = c(...,...) as a vector as shown in the main code but it’s not an easy plot to understand without a clear legend or labels next to the lines as you can see from the image. I’ve struggled trying to create a legend from scratch as I have two different subsets of data – however, if anyone has a solution to this it would avoid all the POSIX/x-axis dilemma.

enter image description here

Still not further forward with the annotation and time data but I did find out where I was going wrong in creating my own legend – found this post after much searching: How to add a color legend to a ggplot with different geom layers

This explained that to add a legend I needed to put my color into the aes() argument of geom_line() and set the colors using scale_fill_manual.

los.plot <- ggplot() +
  geom_line(data = los2 %>%
              ... (as above)
            aes(x=start.time, y=(median/60), color = "AMU Bedded")) +
  geom_line(data = los2 %>%
             ... (as above)
            aes(x=start.time, y=(median / 60), color="AEC")) +
  labs(title = ... (as above)) +
  scale_colour_manual(breaks = c("AMU Bedded", "AEC"),
                      values = c("grey30","magenta"))

I had been setting the color outside of the aes() argument

This now gives:
enter image description here

Which is exactly what I wanted