clions226
clions226

Reputation: 81

Change color of individual facet labels based on groups

I am trying to change the facet label colors of a facet_grid I have. This is an example of a plot I have: enter image description here

and I want the facet boxes (labeled A, B, C) to each be a different color (eg. A = red, B = green, C = blue). I've tried this example which is most similar to what I am trying to do but I keep getting this error when I run the last line of code: Error in grid.Call.graphics(C_setviewport, vp, TRUE) : invalid 'layout.pos.col'

Code:

df <- data.frame(
  type   = c("Small", "X-large", "Medium", "Large", "Small", "X-large", "Medium", "Large", "Small", "X-large", "Medium", "Large"), 
  group   = c("A", "A", "A", "A", "B", "B", "B", "B", "C", "C", "C", "C"),
  value = c(22, 40, 31, 60, 26, 24, 22, 18, 30, 70, 60, 50), 
  error = c(10, 9, 3, 11, 15, 10, 13, 9, 14, 20, 17, 15)
)

(df$type = factor(df$type, levels=c("Small","Medium","Large","X-large")))  
plot <- ggplot(df, aes(y=type, size = 15)) + facet_grid(group ~ ., scales="free_y", space="free_y")
plot <- plot + geom_point(aes(x=value),
                          size=3)
plot

dummy <- ggplot(data = df, aes(y=type, size = 15)) + facet_wrap(group ~ ., scales = "free_y") + 
  geom_rect(aes(fill=group), xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) +
  theme_minimal()
dummy <- dummy + geom_point(aes(x=value),
                            size=3)
dummy
 
g1 <- ggplotGrob(plot)
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 | stript)
grid.newpage()
grid.draw(new_strips)

gtable_stack <- function(g1, g2){
  g1$grobs <- c(g1$grobs, g2$grobs)
  g1$layout <- rbind(g1$layout, g2$layout)
  g1
}

new_plot <- gtable_stack(g1, new_strips)
grid.newpage()
grid.draw(new_plot)

I am sorry this is a repeat question but I can't seem to get this code to work or find another solution which works. I've looked at this other form and a few other posts here but cannot find an answer that works. Any idea what I am doing wrong or how to fix this? Is there an easier way to assign multiple fills in ggplot?

Other posts: Change facet label text and background colour Multiple colors in a facet STRIP background

Thank you!

Upvotes: 2

Views: 2046

Answers (1)

teunbrand
teunbrand

Reputation: 37903

The github version of ggh4x was recently updated to allow these kinds of edits to facet strips. (disclaimer: I'm the author of ggh4x). See example below:

library(ggplot2)
library(ggh4x) # devtools::install_github("teunbrand/ggh4x")

df <- data.frame(
  type   = c("Small", "X-large", "Medium", "Large", "Small", "X-large", "Medium", "Large", "Small", "X-large", "Medium", "Large"), 
  group   = c("A", "A", "A", "A", "B", "B", "B", "B", "C", "C", "C", "C"),
  value = c(22, 40, 31, 60, 26, 24, 22, 18, 30, 70, 60, 50), 
  error = c(10, 9, 3, 11, 15, 10, 13, 9, 14, 20, 17, 15)
)

df$type <- factor(df$type, levels=c("Small","Medium","Large","X-large"))
ggplot(df, aes(value, type, size = 15)) + 
  geom_point() +
  facet_grid2(
    group ~ ., scales="free_y", space="free_y",
    strip = strip_themed(
      background_y = list(element_rect(fill = "red"),
                          element_rect(fill = "green"),
                          element_rect(fill = "blue"))
    )
  )

Created on 2021-07-08 by the reprex package (v1.0.0)

A fair word of warning though: I'm still tinkering with this stuff, so eventual formulation may change.

Upvotes: 3

Related Questions