rggplot2colorscoefplot

Using dwplot to display coefficients by different colors based on some paramaters


I want to create a sjPlot-ish coefficient plot using dwplot() because my model outputs (odds-ratio-lized logit coefs and s.e.) cannot be directly fed into the former. I want the output to display coef > 1 in "#377EB8" and those <= 1 in "#E41A1C" along both sides of the vertical reference line = 1 using sjPlot's default Set1 color palette.

However, I found it difficult to trick R to do what I want, below is my current code:

# load the data
mydf <- readRDS(url("https://www.dropbox.com/s/m6o3aohbu2iwge2/mydf.rds?dl=1"))

library(ggplot2)
library(dotwhisker)

p <- dwplot(df, vline = ggplot2::geom_vline(xintercept = 1,
                                   colour = "grey90",
                                   linetype = 1,
                                   size = 1)) + 
       theme_classic() + 
       theme(legend.position="none", plot.title = element_text(hjust = 0.5, face="bold")) +
       xlab("Odds ratio")
       
p + scale_fill_manual(values=c("#E41A1C", "#377EB8")) +
     geom_segment(aes(x=conf.low,y=term,xend=conf.high,
                      yend=term,col=estimate > 1)) +
     geom_point(aes(x=estimate,y=term,col=estimate > 1))

But the colors of the output look strange, don't look quite like the exact color scheme shown in Set1. I've referenced this earlier post but can't find a good walk-around to solve this problem, perhaps there's something wrong with my arguments inside the geom_segment() and geom_point() function. It will be appreciated if someone could shed some light on this. output


Solution

  • The issue is that you use scale_fill_manual but map on the color aes, i.e. use scale_color_manual. Additionally under the hood there is already something mapped on the color which results in an error

    Insufficient values in manual scale. 3 needed but only 2 provided.

    This could be fixed by using a named color vector (or by setting the limits) which also ensures that the right colors are assigned to the categories.

    library(ggplot2)
    library(dotwhisker)
    
    p <- dwplot(mydf, vline = ggplot2::geom_vline(
      xintercept = 1,
      colour = "grey90",
      linetype = 1,
      size = 1
    )) +
      theme_classic() +
      theme(legend.position = "none", plot.title = element_text(hjust = 0.5, face = "bold")) +
      xlab("Odds ratio")
    
    p + 
      scale_color_manual(values = c("FALSE" = "#E41A1C", "TRUE" = "#377EB8")) +
      geom_segment(aes(
        x = conf.low, y = term, xend = conf.high,
        yend = term, col = estimate > 1
      )) +
      geom_point(aes(x = estimate, y = term, col = estimate > 1))
    

    enter image description here

    DATA

    structure(list(term = structure(1:5, names = c("X1", "X2", "X3", 
    "X4", "X5"), levels = c("X1", "X2", "X3", "X4", "X5"), class = "factor"), 
        estimate = c(0.990945229592862, 1.01649975436596, 0.981822272245729, 
        1.00200300047509, 1.11234308470697), conf.low = c(0.978268803948375, 
        1.0054731859839, 0.970707803486251, 0.993648103170243, 1.10200032988942
        ), conf.high = c(1.00118816776943, 1.02503427463924, 0.993972524876506, 
        1.01282670058945, 1.12476153238761), sign = c("#377EB8", 
        "#E41A1C", "#377EB8", "#E41A1C", "#E41A1C")), row.names = c("X1", 
    "X2", "X3", "X4", "X5"), class = "data.frame")