Search code examples
rggplot2facet-wrapgeom-point

Color and order of coefficients within scale_fill_manual not consistent


As you can see with my code and data below, I am trying to reorder the coefficients by demographic group, so the order is (from top to bottom): Black, Hispanic, White, Female, Male.

What I'm trying to do within scale_fill_manual seems to rearrange the coefficients correctly in the legend only--the colors/coefficients in the actual plot do not seem to follow. What am I missing here?

Code:

dtest %>% 
  ggplot(aes(x = coef, y = as.factor(model),
             xmin = ci_lower, xmax = ci_upper,
             color = category)) +
  facet_wrap(~outcome, 
             nrow = 3,
             scales = "free") +
  geom_errorbar(width = 0, 
                size = 1.1, 
                alpha = 0.6, 
                position = position_dodge(width = 0.5)) +
  geom_errorbar(aes(x = -coef, xmin = -ci_lower, xmax = -ci_upper),
            width = 0, 
            size = 1.1, 
            alpha = 0, 
            position = position_dodge(width = 0.5)) +
  geom_point(shape = 22, 
             aes(fill = category), 
             size = 2.5, 
             color = 'white',
             position = position_dodge(width = 0.5)) +
  geom_vline(xintercept = 0, 
             linetype = "dashed", 
             color = "blue",
             linewidth = .3) +
  scale_y_discrete(labels = outcome_labels) +
  scale_fill_manual(limits = c("Black", "Hispanic", "White", "Female", "Male"),                 
                    values = c("Black" = "indianred2",
                               "Hispanic" = "tan2",
                               "White" = "lightgoldenrod1",
                               "Female" = "gray10",
                               "Male" = "gray70")) +
  scale_color_manual(limits = c("Black", "Hispanic", "White", "Female", "Male"),
                     values = c("Black" = "indianred2",
                               "Hispanic" = "tan2",
                               "White" = "lightgoldenrod1",
                               "Female" = "gray10",
                               "Male" = "gray70")) +
  theme_bw(base_size = 14) +
  theme(legend.title = element_blank())

Data:

dtest <- structure(list(model = c(7, 6, 5, 7, 6, 5, 4, 3, 4, 3, 2, 1, 
2, 1, 7, 6, 5, 7, 6, 5, 7, 6, 5, 4, 3, 4, 3, 4, 3, 2, 1, 2, 1, 
2, 1), category = c("Female", "Female", "Female", "Male", "Male", 
"Male", "Female", "Female", "Male", "Male", "Female", "Female", 
"Male", "Male", "Hispanic", "Hispanic", "Hispanic", "Black", 
"Black", "Black", "White", "White", "White", "Hispanic", "Hispanic", 
"Black", "Black", "White", "White", "Hispanic", "Hispanic", "Black", 
"Black", "White", "White"), outcome = c("ysr", "ysr", "ysr", 
"ysr", "ysr", "ysr", "ss", "ss", "ss", "ss", "poverty", "poverty", 
"poverty", "poverty", "ysr", "ysr", "ysr", "ysr", "ysr", "ysr", 
"ysr", "ysr", "ysr", "ss", "ss", "ss", "ss", "ss", "ss", "poverty", 
"poverty", "poverty", "poverty", "poverty", "poverty"), coef = c(0.0224673769230769, 
0.124678274725275, -0.0157007538461538, 0.328996120879121, 0.334152318681319, 
0.286053692307692, -0.252022263736264, -0.195319505494505, -0.304987736263736, 
-0.233133758241758, 0.298986065934066, 0.23503343956044, 0.391878274725275, 
0.0414132626373626, 0.167719824175824, 0.246736065934066, 0.0900949098901099, 
0.197205582417582, 0.238663087912088, 0.19849110989011, -0.235474142857143, 
-0.220236802197802, -0.265119164835165, -0.223690175824176, -0.198643747252747, 
-0.221460516483516, -0.123310659340659, -0.704752681318681, -0.139090043956044, 
0.451706428571429, 0.24867232967033, 0.248139373626374, 0.0291924879120879, 
-0.149548362637363, 0.762050692307692), ci_lower = c(-0.214028681318681, 
-0.103655473626374, -0.273158362637363, 0.159887417582418, 0.153449428571429, 
0.0967789153846154, -0.583139351648352, -0.421394230769231, -0.602876417582418, 
-0.450184747252747, -0.0486217065934066, -0.0487711857142857, 
-0.00532261956043956, -0.278972626373626, -0.0353962637362637, 
0.0344971626373626, -0.150122417582418, -0.051963521978022, -0.0029050167032967, 
-0.0624020428571429, -0.594504516483516, -0.591095197802198, 
-0.684788, -0.625167901098901, -0.433024010989011, -0.61050443956044, 
-0.36732256043956, -1.18117032967033, -0.840628142857143, -0.0308338549450549, 
0.00663712505494506, -0.132468450549451, -0.337184494505494, 
-0.355178835164835, -0.345514043956044), ci_upper = c(0.258963450549451, 
0.353012010989011, 0.241756846153846, 0.498104846153846, 0.514855230769231, 
0.475328472527473, 0.0790948637362637, 0.0307552087912088, -0.00709903648351648, 
-0.0160827648351648, 0.646593868131868, 0.518838065934066, 0.789079164835165, 
0.361799142857143, 0.370835901098901, 0.458974956043956, 0.330312241758242, 
0.446374703296703, 0.480231186813187, 0.459384263736264, 0.123556252747253, 
0.15062156043956, 0.154549703296703, 0.177787527472527, 0.0357365087912088, 
0.167583406593407, 0.120701252747253, -0.228335010989011, 0.562448098901099, 
0.934246736263736, 0.490707516483517, 0.628747197802198, 0.395569472527473, 
0.0560821087912088, 1.86961538461538)), row.names = c(NA, -35L
), class = c("tbl_df", "tbl", "data.frame"))


Solution

  • The issue is that via limits you set the order of the legend entries but the order in the plot still follows the order of your categoryies, which if not set are ordered alphabetically. To fix that, convert category to a factor with your desired order.

    library(ggplot2)
    
    dtest$category <- factor(
      dtest$category,
      rev(c("Black", "Hispanic", "White", "Female", "Male"))
    )
    
    ggplot(dtest, aes(
      x = coef, y = as.factor(model),
      xmin = ci_lower, xmax = ci_upper,
      color = category
    )) +
      facet_wrap(~outcome,
        nrow = 3,
        scales = "free"
      ) +
      geom_errorbar(
        width = 0,
        size = 1.1,
        alpha = 0.6,
        position = position_dodge(width = 0.5)
      ) +
      geom_errorbar(aes(x = -coef, xmin = -ci_lower, xmax = -ci_upper),
        width = 0,
        size = 1.1,
        alpha = 0,
        position = position_dodge(width = 0.5)
      ) +
      geom_point(
        shape = 22,
        aes(fill = category),
        size = 2.5,
        color = "white",
        position = position_dodge(width = 0.5)
      ) +
      geom_vline(
        xintercept = 0,
        linetype = "dashed",
        color = "blue",
        linewidth = .3
      ) +
      # scale_y_discrete(labels = outcome_labels) +
      scale_fill_manual(
        limits = rev,
        values = c(
          "Black" = "indianred2",
          "Hispanic" = "tan2",
          "White" = "lightgoldenrod1",
          "Female" = "gray10",
          "Male" = "gray70"
        ),
        aesthetics = c("fill", "color")
      ) +
      theme_bw(base_size = 14) +
      theme(legend.title = element_blank())
    

    enter image description here