Search code examples
rggplot2facetfacet-wrap

Changing point colors for only one panel using facet_wrap()


I am trying to plot a bunch of model results using facet_wrap() and want to change the colors of the points and error bars to being red for "ses" but for only panel 3. So far I haven't quite figured out how to do this successfully. Any ideas?

Here is some (very shortened) example code and data:

Code:

ggplot(d, aes(x = var, y = coef,
              ymin = ci_lower, ymax = ci_upper,
              color = var)) +
  geom_point() +
  geom_errorbar(width = .1) +
  facet_wrap(~model, nrow = 1) +
  labs(title = "Model results",
       y = "Coefficient",
       x = "") +
  geom_hline(yintercept = 0, linetype = "solid", color = "black", size = .5) +
  coord_flip() +
  scale_color_manual(values = c("white" = "blue",
                                "score" = "black",
                                "female" = "black",
                                "ses" = "black")) +
  theme_bw(base_size = 12)

Data:

structure(list(var = c("white", "score", "female", "ses", "white", 
"score", "female", "ses", "white", "score", "female", "ses"), 
    coef = c(0.7, 0.5, 0.6, -0.4, 0.2, 1.02, 0.1, -0.1, 0.3, 
    0.4, 0.5, 0.2), ci_lower = c(0.4, 0.05, 0.3, -0.7, -0.1, 
    0.52, -0.2, -0.4, -0.1, 0.1, 0.2, -0.1), ci_upper = c(1, 
    0.9, 0.9, -0.1, 0.5, 1.4, 0.4, 0.2, 0.6, 0.7, 0.8, 0.5), 
    model = c(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3)), class = c("spec_tbl_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -12L), spec = structure(list(
    cols = list(var = structure(list(), class = c("collector_character", 
    "collector")), coef = structure(list(), class = c("collector_double", 
    "collector")), ci_lower = structure(list(), class = c("collector_double", 
    "collector")), ci_upper = structure(list(), class = c("collector_double", 
    "collector")), model = structure(list(), class = c("collector_double", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
    "collector")), skip = 1L), class = "col_spec"))

Solution

  • One option would be to recode your var column where you assign a different value for var="ses" and model=3 which would allow you to assign a red color for "ses" in panel 3:

    library(ggplot2)
    
    d$color <- ifelse(d$var == "ses" & d$model == 3, "ses_red", d$var)
    
    ggplot(d, aes(x = var, y = coef,
                  ymin = ci_lower, ymax = ci_upper,
                  color = color)) +
      geom_point() +
      geom_errorbar(width = .1) +
      facet_wrap(~model, nrow = 1) +
      labs(title = "Model results",
           y = "Coefficient",
           x = "") +
      geom_hline(yintercept = 0, linetype = "solid", color = "black", size = .5) +
      coord_flip() +
      scale_color_manual(values = c("white" = "blue",
                                    "score" = "black",
                                    "female" = "black",
                                    "ses" = "black",
                                    "ses_red" = "red")) +
      theme_bw(base_size = 12)
    

    Depending on your desired result a second option would be to split your dataset and use multiple layers:

    library(ggplot2)
    library(dplyr)
    
    d1 <- d |> 
      filter(!(var == "ses" & model == 3))
    
    d2 <- d |> 
      filter(var == "ses" & model == 3)
    
    ggplot(d1, aes(x = var, y = coef,
                  ymin = ci_lower, ymax = ci_upper,
                  color = var)) +
      geom_point() +
      geom_errorbar(width = .1) +
      geom_point(data = d2, color = "red") +
      geom_errorbar(data = d2, color = "red", width = .1) +
      facet_wrap(~model, nrow = 1) +
      labs(title = "Model results",
           y = "Coefficient",
           x = "") +
      geom_hline(yintercept = 0, linetype = "solid", color = "black", size = .5) +
      coord_flip() +
      scale_color_manual(values = c("white" = "blue",
                                    "score" = "black",
                                    "female" = "black",
                                    "ses" = "black")) +
      theme_bw(base_size = 12)