Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using scale_color with a variable of class date produces Error: as.Date.numeric(value) : 'origin' must be supplied

I'm trying to color by date with ggplot2, but when I try to customize the color using scale_color_gradient2, I get an error saying Error in as.Date.numeric(value) : 'origin' must be supplied.

I can't seem to figure out how to pass the origin to scale_color_gradient2.

I've provided an example below. Any advice?

set.seed(1)
x1 <- rnorm(100)
x2 <- rnorm(100)
day <- sample(seq(as.Date('1999/01/01'), as.Date('2000/01/01'), by="day"), 100)

myData <- data.frame(x1, x2, day)

# this plot works as expected
ggplot(myData, aes(x = x1, y = x2, color = day)) + geom_point()

# scale_color_gradient2() asks for an origin, but I can't figure out how to supply one
ggplot(myData, aes(x = x1, y = x2, color = day)) + geom_point() +
    scale_color_gradient2()
like image 383
James Wade Avatar asked Mar 05 '23 12:03

James Wade


1 Answers

Two things need to be added to scale_color_gradient2: trans = "date"* and a sensible midpoint (default is 0). I used mean 'day'. Note that you need the numeric version of the mean in scale:

ggplot(myData, aes(x = x1, y = x2, color = day)) +
  geom_point() +
  scale_color_gradient2(trans = "date", midpoint = as.numeric(mean(myData$day)))

enter image description here


You may want to change the default breaks and labels in the legend. First, create a sequence of breaks, using seq or pretty:

brk <- seq.Date(min(myData$day), max(myData$day), by = "3 month")
# brk <- pretty(myData$day)

Set breaks and labels with desired format in your scale:

scale_color_gradient2(trans = "date", midpoint = as.numeric(mean(myData$day)), 
                      breaks = brk,
                      labels = format(brk, "%Y-%m")) 

Edit following comment:

Use scale_color_gradient2 with POSIXct variable

Add trans = "time" and a sensible midpoint to scale_color_gradient2. Here I use a mean 'time'. Note that you need the numeric version of the mean in scale.

# some data
d <- data.frame(x = 1:10, y = 1, time = as.POSIXct("2019-02-15 12:00") + 1:10)

ggplot(d, aes(x = x, y = y, color = time)) +
  geom_point() +
  scale_color_gradient2(trans = "time", midpoint = as.numeric(mean(d$time)))

enter image description here


Possibly change breaks and labels in the legend, e.g.

brk <- pretty(d$time)

ggplot(d, aes(x = x, y = y, color = time)) +
  geom_point() +
  scale_color_gradient2(trans = "time", midpoint = as.numeric(mean(d$time)),
                        breaks = brk, labels = format(brk, format = "%H:%M:%S"))

*In the current version of ggplot2 (3.1.0), it is not obvious from the docs that trans = "date" and trans = "time" exist. They are mentioned neither in the trans argument in ?scale_color_gradient et al., nor in ?continuous_scale. However, I submitted an issue so the docs will hopefully be updated in the next release.

like image 130
Henrik Avatar answered Mar 10 '23 16:03

Henrik