1

I want to fill a histogram different colors based on date ranges. In the example below, the entire histogram is orange. Let's say I want fill dates 2012-03-01 to 2012-04-28 a different color and keep the rest orange.

library(ggplot2)
library(lubridate)
# random dates
# https://stackoverflow.com/questions/14720983/efficiently-generate-a-random-sample-of-times-and-dates-between-two-dates
randdate <- function(N, st="2012/01/01", et="2012/12/31") {
              st <- as.POSIXct(as.Date(st))
              et <- as.POSIXct(as.Date(et))
              dt <- as.numeric(difftime(et,st,unit="sec"))
              ev <- sort(runif(N, 0, dt))
              rt <- st + ev
            }
set.seed(42)
dat <- data.frame(y=sample(c(0:50), 1000, replace=TRUE),
                  date=randdate(1000))
dat$date <- ymd(substr(dat$date, 1, 10))

ggplot(dat,
       aes(x=date)) +
       geom_histogram(binwidth=400000, 
                      fill="#E69F00", 
                      colour="#E69F00") +
       scale_x_datetime(labels=date_format("%m-%Y"),
                        breaks=date_breaks("1 year"))

Hadley's answer here suggests fill=..x.., but I have not had luck getting it to work with dates. Any ideas?

Community
  • 1
  • 1
Eric Green
  • 7,385
  • 11
  • 56
  • 102

1 Answers1

1

If you just extend the example Hadley included with the cut function you'll get what you want.

ggplot(dat,
   aes(x=date, 
       fill=cut(..x.., 
       breaks=c(min(..x..), as.POSIXct("2012-03-01"), as.POSIXct("2012-04-28"), max(..x..)),
       labels=c("before","during","after"), include.lowest=TRUE)
   )) +
   geom_histogram(binwidth=400000) +
   scale_x_datetime(labels=date_format("%m-%Y"),
                    breaks=date_breaks("1 year")) +
   scale_fill_discrete(name="Range")

enter image description here

MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • Thanks, @MrFlick. Previously, before I used `cut`, I was able to run the following to add a vertical line segment: `geom_segment(x=as.numeric(ymd("2012-05-27")),y=0,xend=as.numeric(ymd("2012-05-27")),yend=20,linetype=1,colour="#999999")`. Now I'm getting an error that `x` cannot be found. I've tried a few different formats for `x`, but I have not found the right one yet. How could I add this line segment to the plot in your answer? – Eric Green Oct 09 '14 at 03:44
  • Wwell, you're not going to want to use the `fill=` aesthetic in the `geom_segment` layer so move the `aes()` to the `geom_histogram` or set `inherit.aes = FALSE` in the `geom_segment` – MrFlick Oct 09 '14 at 03:49
  • `inherit.aes = FALSE` it is. did not know about that option. great solution. – Eric Green Oct 09 '14 at 03:52