Skip to content

Instantly share code, notes, and snippets.

@mikmart
Last active September 30, 2024 21:33
Show Gist options
  • Save mikmart/bfbf62839fbdd162b4b88e6d43e0c858 to your computer and use it in GitHub Desktop.
Save mikmart/bfbf62839fbdd162b4b88e6d43e0c858 to your computer and use it in GitHub Desktop.
Reversing a time axis in ggplot2

An answer to this closed StackOverflow question about reversing a time axis in ggplot2.

date = c("2011-11-15", "2011-11-16", "2011-11-17", "2011-11-19")
start = c("12:01:27", "12:01:25", "12:01:02", "12:01:12")
end = c("12:30:15", "12:32:15", "12:39:12", "12:30:18")

df = data.frame(date = as.POSIXct(date),
     ystart = as.POSIXct(start, format="%H:%M:%S"), 
     yend = as.POSIXct(end, format="%H:%M:%S"),
     xstart=as.POSIXct(paste(date, "12:00:00"), format="%Y-%m-%d %H:%M:%S"),
     xend = as.POSIXct(paste(date, "14:00:00"), format="%Y-%m-%d %H:%M:%S"))

Following this answer you can create a custom scale transformer that applies both a time and a reverse transformation to the y-axis to get the output that you are looking for. (It seems a recent new release has broken the linked answer, which required a minor modification to work again.)

library(scales)
library(ggplot2)

p <- ggplot(df) +
  geom_rect(aes(ymin = ystart, ymax = yend, xmin = xend, xmax = xstart))

c_trans <- function(a, b, breaks = b$breaks, format = b$format, domain = b$domain) {
  a <- as.trans(a)
  b <- as.trans(b)

  name <- paste(a$name, b$name, sep = "-")

  trans <- function(x) a$trans(b$trans(x))
  inv <- function(x) b$inverse(a$inverse(x))

  trans_new(name, trans, inv, breaks, format = format, domain = domain)
}

rev_date <- c_trans("reverse", "time")

p + scale_y_continuous(trans = rev_date)

Created on 2018-07-18 by the reprex package (v0.2.0.9000).

@mikmart
Copy link
Author

mikmart commented Sep 30, 2024

Updated to fix this particular example, but I haven't tested it particularly thoroughly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment