Search code examples
rggplot2facet

Conditionally change ggplot facet background with date axis


Using facet_grid with ggplot, I'm trying to conditionally change the background of some the panels, to highlight ones of interest I've identified. I'm trying to achieve this following the answer from a similar question here.

I understand the idea is to plot a geom_rect layer with opacity first to act as the background, but I believe the isolated problem is that when passing parameters to the rect, they clash with my actual x-axis being a date stamp, leaving the error

Error: Continuous value supplied to discrete scale

Below is a minimal example reproducing the problem:

dat = read.table(text = "2014-01-25 1  A
2014-02-05 1  A
2014-09-01 1  A
2014-08-26 2  B
2014-12-12 2  C", col.names = c("Date", "Vehicle", "Problem"))

facetcond = data.frame("Vehicle" = 2, "Problem" = "B")

ggplot(dat) +
  theme_bw() + 
  geom_rect(data = facetcond, aes(fill = "red"), 
    xmin = as.Date("2012-01-01"), # I've also tried Inf and 
    xmax = as.Date("2016-01-01"), # -Inf here
    ymin = -Inf, 
    ymax = Inf, alpha = 0.3) +
  geom_bar(aes(x = as.Date(Date), fill = Vehicle), binwidth = 14) +
  facet_grid(Problem~Vehicle, margins = "Problem")

Any help would be greatly appreciated, I've tried a number of different approaches with little success.


Solution

  • The cause of your error message was that you tried to map an aesthetic to a column that doesn't exist in your data, in this line:

    geom_rect(data = facetcond, aes(fill = "red"), 
    

    You are not mapping an aesthetic, but telling ggplot to fill the rectangle with red. The line should be:

    geom_rect(data = facetcond, fill = "red", 
    

    Also, you will also save yourself some trouble by converting the original data frame dates to as.Date() prior to plotting. Note that I use colClasses to convert the data directly into the class I want, including "Date".

    Here is the complete working solution.

    library(ggplot2)
    
    dat = read.table(text = "2014-01-25 1  A
    2014-02-05 1  A
                     2014-09-01 1  A
                     2014-08-26 2  B
                     2014-12-12 2  C", 
                     col.names = c("Date", "Vehicle", "Problem"), 
                     colClasses = c("Date", "integer", "factor"))
    
    facetcond = data.frame("Vehicle" = 2, "Problem" = "B")
    
    ggplot(dat) +
      theme_bw() + 
      geom_rect(data = facetcond, fill = "red", 
                xmin = -Inf, # I've also tried Inf and 
                xmax = Inf, # -Inf here
                ymin = -Inf, 
                ymax = Inf, alpha = 0.3) +
      geom_bar(aes(x = Date, fill = Vehicle), binwidth = 14) +
      scale_x_date() +
      facet_grid(Problem~Vehicle, margins = "Problem")
    

    enter image description here