oneyellowlion
oneyellowlion

Reputation: 365

R / ggplot2: How to make a facet panel label background color conditional on a value in another column in the dataframe

Here's the code I'm using to plot a regression line for each US state, using facet wrapping in ggplot2:

ggplot(data = allYearsSlope, aes(x = year, y = residual)) +
  geom_smooth(method = "lm", se = FALSE) +
  facet_wrap(~ state, ncol = 8) +
  theme(
          strip.text = element_text(size = rel(0.5), face = "bold"),
          panel.background = element_rect(fill = "white"),
          panel.border = element_rect(color="purple",fill=NA),
          plot.background = element_blank(),
          axis.ticks.x = element_blank()
        )  +
  scale_x_continuous(labels = NULL) 

It works fine. But now I'm trying to color the facet panel label (the box that, in this case, contains the name of the state that appears above each panel) according to a value ("blue" or "green") that I'm storing in the dataframe that contains the rest of the data. The color is stored in allYearsSlope$panelColor. Having a really hard time figuring out how to do this.

I've read the solution here: Conditional formatting of panel background in GGplot2. Along with the few other SO answers it refers to. But I don't really see a way to do this coming out of those answers. Any ideas, anyone?

Big thanks for any help.

Upvotes: 3

Views: 1451

Answers (1)

Allan Cameron
Allan Cameron

Reputation: 174556

The least hacky way I know of to do this is via the ggh4x package:

library(ggh4x)
#> Loading required package: ggplot2

ggplot(iris, aes(Sepal.Width, Petal.Length)) +
  geom_point() +
  geom_smooth(formula = y ~ x, method = "lm") +
  facet_grid2(.~Species, scales = 'free',
               strip = strip_themed(
                 background_x = list(element_rect(fill = "red"),
                                     element_rect(fill = "green"),
                                     element_rect(fill = "yellow")))) 

Created on 2022-12-24 with reprex v2.0.2


Edit

It's not possible to map strip color as an aesthetic, so this needs to be done by writing your own automation. Instead of passing a list of element_rect manually, we can create a list of element_rect whose fill color is dependent on the properties of a regression each faceted subset. This isn't quite as tricky as it sounds. Here for example, we color the strips according to the slope of the regression line in the panel - red for < 0.5 and green for > 0.5:

library(ggh4x)

ggplot(iris, aes(Sepal.Width, Petal.Length)) +
  geom_point() +
  geom_smooth(formula = y ~ x, method = "lm") +
  facet_grid2(.~Species, scales = 'free',
              strip = strip_themed(
                background_x = lapply(split(iris, iris$Species), function(x) {
                  element_rect(fill = ifelse(
                    coef(lm(Petal.Length ~ Sepal.Width, data = x))[2] < 0.5,
                    "red", 
                    "green"))
                })
                ))

enter image description here

Upvotes: 1

Related Questions