Conditionally modify ggplot theme based on presence of facets?

I think Oliver was thinking in the correct direction.

I don't think the theme_custom function is the correct place to check the plot for conditional theming, because theme functions are mostly agnostic about the precise plot that they are added to.

Instead, I think the appropriate place to check the plot is when the theme is added to the plot. You could write a theme function like the following, which sets a different class to the output.

theme_custom <- function() {
  out <- theme_minimal()
  class(out) <- c("conditional_theme", class(out))
  out
}

Now everytime a theme is added to a plot, this is done through the ggplot_add.theme function, which we can rewrite for the conditional_theme class. In my opinion, the correct way to check if a plot is facetted, is to check the class of the plot$facet slot, which can be FacetGrid, FacetWrap etc when a proper facet is added and defaults to FacetNull when no facet is set.

ggplot_add.conditional_theme <- function(object, plot, object_name) {
  if (!inherits(plot$facet, "FacetNull")) {
    object <- object + theme(panel.border = element_rect(colour = "grey50", fill = NA))
  }
  plot$theme <- ggplot2:::add_theme(plot$theme, object, object_name)
  plot
}

And now the use cases should work as intended:

ggplot(mtcars, aes(mpg, wt)) +
  geom_point() +
  facet_wrap(vars(cyl)) +
  theme_custom()

enter image description here

ggplot(mtcars, aes(mpg, wt)) +
  geom_point() +
  theme_custom() 

enter image description here

The only downside is that you would literally have to add the theme to the plot every time and you can't use the theme_set(theme_custom()) to have this apply to any plot in the session.

Tags:

R

Ggplot2