Search code examples
rggplot2visualizationggeffects

plotting 3-way interaction with ggeffects, theme changes not being applied to all facets


I'm using the plot and predict functions from ggeffects to plot a 3-way interaction. The plots are being generated, but when I try to apply theme changes they only get applied to the second facet, see below

library(ggeffects)
library(ggplot2)

dat_iris <- iris

dat_iris$Petal.Size <- ifelse(dat_iris$Petal.Length <= 3, "small", "big")

model_iris <- glm(Sepal.Length ~ Sepal.Width*Species + Petal.Width + Petal.Size, data = dat_iris)

gg_iris <- plot(ggpredict(model_iris, terms=c("Sepal.Width", "Species", "Petal.Width", "Petal.Size")),  colors = c("#190C3EFF", "#9C2964FF", "#F8870EFF"))

gg_iris

gg_iris +
  xlab("Sepal Width") +
  ylab("Sepal Length") +
  guides(color = guide_legend("Species"), fill = guide_legend("Species")) +
  theme_minimal() +
  theme(panel.grid.major = element_line(color = "#E5E5E5", linetype = "dashed", linewidth = 0.3),
        panel.background = element_rect(fill = "white", color = NA),
        plot.title = element_blank(),
        legend.title = element_text(face = "bold", size = 9),
        legend.text = element_text(size = 9),
        legend.position = "right",
        axis.title.x = element_text(face = "bold", size = 9), 
        axis.title.y = element_text(face="bold", size = 9),
        strip.background = element_rect(fill = "#F0F0F0", color = NA),
        strip.text = element_text(face = "bold", size = 9)) +
  scale_y_continuous(breaks = 4:8) +
  scale_x_continuous(breaks = 2:5)

The resulting image looks like this:

ggeffects 3-way interaction

I have read the ggeffects documentation, which states that "Load library(ggplot2) and use theme_set(theme_ggeffects()) to set the ggeffects-theme as default plotting theme. You can then use further plot-modifiers, e.g. from sjPlot, like legend_style() or font_size() without losing the theme-modifications." However this is does not seem to work with normal ggplot2 theme adjustments. Even following the documentation here https://strengejacke.github.io/ggeffects/articles/ggeffects.html, theme changes only get applied to one facet

gg_iris + theme(legend.position = "bottom")

enter image description here

I also tried manually faceting like this plot(ggpredict(model_iris, terms=c("Sepal.Width", "Species", "Petal.Width")), colors = c("#190C3EFF", "#9C2964FF", "#F8870EFF")) + facet_wrap(~"Petal.Size") but this resulted in super bizarre output.

manual facetting

Is there a way to get the theme changes applied to all facets?


Solution

  • ggeffects uses patchwork to arrange the plots (facets are used within each of the two main panels), so you can apply themes and scales in the way you would to a patchwork object.

    That is, use & instead of + to apply themes and scales to all the plots in the arrangement, and plot_layout(guides="collect") to use the same legend for all plots.

    So:

    gg_iris +
      plot_layout(guides="collect") &
      xlab("Sepal Width") &
      ylab("Sepal Length") &
      scale_y_continuous(breaks = 4:8) &
      scale_x_continuous(breaks = 2:5) & 
      guides(color = guide_legend("Species"), fill = guide_legend("Species")) &
      theme_minimal() &
      theme(panel.grid.major = element_line(color = "#E5E5E5", linetype = "dashed", linewidth = 0.3),
            panel.background = element_rect(fill = "white", color = NA),
            plot.title = element_blank(),
            legend.title = element_text(face = "bold", size = 9),
            legend.text = element_text(size = 9),
            legend.position = "bottom",
            axis.title.x = element_text(face = "bold", size = 9), 
            axis.title.y = element_text(face="bold", size = 9),
            strip.background = element_rect(fill = "#F0F0F0", color = NA),
            strip.text = element_text(face = "bold", size = 9))
    
    

    enter image description here