1

To a 3 year old post ggplot2: facet_wrap strip color based on variable in data set

Baptiste has given the following solution:

d <- data.frame(fruit = rep(c("apple", "orange", "plum", "banana", "pear", "grape")), 
            farm = rep(c(0,1,3,6,9,12), each=6), 
            weight = rnorm(36, 10000, 2500), 
            size=rep(c("small", "large")))

 p1 = ggplot(data = d, aes(x = farm, y = weight)) + 
 geom_jitter(position = position_jitter(width = 0.3), 
          aes(color = factor(farm)), size = 2.5, alpha = 1) + 
 facet_wrap(~fruit)

dummy <- ggplot(data = d, aes(x = farm, y = weight))+ facet_wrap(~fruit)  + 
 geom_rect(aes(fill=size), xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) +
theme_minimal()

library(gtable)

g1 <- ggplotGrob(p1)
g2 <- ggplotGrob(dummy)

gtable_select <- function (x, ...) 
 {
  matches <- c(...)
  x$layout <- x$layout[matches, , drop = FALSE]
  x$grobs <- x$grobs[matches]
   x
  }

  panels <- grepl(pattern="panel", g2$layout$name)
  strips <- grepl(pattern="strip-t", g2$layout$name)
  g2$layout$t[panels] <- g2$layout$t[panels] - 1
  g2$layout$b[panels] <- g2$layout$b[panels] - 1

  new_strips <- gtable_select(g2, panels | strips)

  library(grid)
  grid.newpage()
  grid.draw(new_strips)

 gtable_stack <- function(g1, g2){
 g1$grobs <- c(g1$grobs, g2$grobs)
 g1$layout <- transform(g1$layout, z= z-max(z), name="g2")
 g1$layout <- rbind(g1$layout, g2$layout)
 g1
 }
 ## ideally you'd remove the old strips, for now they're just covered
 new_plot <- gtable_stack(g1, new_strips)
 grid.newpage()
 grid.draw(new_plot)

(I have just updated the "strip-t" pattern and opened the grid library as it was suggested in the old post)

I repost this because it's an old brillant stuff and I want to use it myself for a presentation. I'm a beginner in ggplot and this could also help me for various scripts.

Here are my questions : - How is it possible to choose the color and not to give the same blue and red please? In my script, I have 3 colors to set, and I hope it can be less agressive. Is it possible to do it ? - Another question, is it possible to integrate this in the legend, i.e to know what are this colors refering ?

Many thanks

Community
  • 1
  • 1
J.marine
  • 69
  • 1
  • 8

1 Answers1

1

you can change the strip colours with the fill scale in the dummy plot. Combining the legends is a bit tricky, but here's a starting point.

enter image description here

library(ggplot2)
library(gtable)
library(gridExtra)
library(grid)

gtable_stack <- function(g1, g2){
  g1$grobs <- c(g1$grobs, g2$grobs)
  g1$layout <- transform(g1$layout, z= z-max(z), name="g2")
  g1$layout <- rbind(g1$layout, g2$layout)
  g1
}

gtable_select <- function (x, ...) 
{
  matches <- c(...)
  x$layout <- x$layout[matches, , drop = FALSE]
  x$grobs <- x$grobs[matches]
  x
}


d <- data.frame(fruit = rep(c("apple", "orange", "plum", "banana", "pear", "grape")), 
                farm = rep(c(0,1,3,6,9,12), each=6), 
                weight = rnorm(36, 10000, 2500), 
                size=rep(c("small", "large")))

p1 = ggplot(data = d, aes(x = farm, y = weight)) + 
  geom_jitter(position = position_jitter(width = 0.3), 
              aes(color = factor(farm)), size = 2.5, alpha = 1) + 
  facet_wrap(~fruit)

dummy <- ggplot(data = d, aes(x = farm, y = weight))+ facet_wrap(~fruit)  + 
  geom_rect(aes(fill=size), xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) +
  theme_minimal() + scale_fill_brewer(palette = "Pastel2") 


g1 <- ggplotGrob(p1)
g2 <- ggplotGrob(dummy)

# extract legends
leg <- g1$grobs[[grep("guide-box", g1$layout$name)]]
dummy_leg <- g2$grobs[[grep("guide-box", g2$layout$name)]]
combined_leg <- rbind.gtable(leg, dummy_leg)
g1$grobs[[grep("guide-box", g1$layout$name)]] <- combined_leg

# move dummy panels one cell up
panels <- grepl(pattern="panel", g2$layout$name)
strips <- grepl(pattern="strip-t", g2$layout$name)
g2$layout$t[panels] <- g2$layout$t[panels] - 1
g2$layout$b[panels] <- g2$layout$b[panels] - 1

new_strips <- gtable_select(g2, panels | strips)

# stack new strips on top of gtable
# ideally you'd remove the old strips, for now they're just covered
new_plot <- gtable_stack(g1, new_strips)

grid.newpage()
grid.draw(new_plot)
baptiste
  • 75,767
  • 19
  • 198
  • 294
  • Thank you so much, this plot is amazing and yes, it was kind of tricky.. thank's for the pedagogy too! – J.marine May 21 '17 at 00:29