How to get color AND linetype to work for multiple-line ROC in ggplot/tidyverse?

Hello,

I would like to compare the ROCs for two predictors (not groups) on a single plot, in black and white. I have been able to generate a plot that changes the colour for both lines to black using scale_color_manual, but scale_linetype_manual using the same format does not work.

Here's a reprex:

gl <- ggroc(list(vs_control=rocobj, vs_nonabs=rocobj2), legacy.axes = TRUE) +
  geom_line(size=1.2) +
  scale_x_continuous("False-Positive Rate") +
  scale_y_continuous("True-Positive Rate") +
  scale_color_manual(breaks = c("vs_control", "vs_nonabs"),
                     values=c("black","black"), labels=c("vs Controls","vs Non-Absconds")) +
  scale_linetype_manual(breaks = c("vs_control", "vs_nonabs"),
                        values=c("solid","dashed"), labels=c("vs Controls","vs Non-Absconds")) +
  geom_segment(aes(x = 0, xend = 1, y = 0, yend = 1), color="black", linetype="dotted") + 
  theme(axis.text=element_text(size=20)) +
  theme(text = element_text(size=20,face="bold")) +
  theme(legend.title=element_blank()) +
  theme(legend.position=c(.8,.2))
gl

The goal is to have both variables clearly differentiated if printed in a black and white journal (using geom_point, linetype, etc). Is there a workaround for this?

Thanks!

This is what works in plain ggplot. Notice that I included color and linetype in the aes() call. I do not know how that works in ggroc. I also used a named vector for the colors, which I think makes the code easier to understand. I used a red color to make sure the color was actually having an effect.

[It isn't really a reprex if data are not included. I invented my own.]

library(ggplot2)
DF <- data.frame(X = 1:10, vs_control = 1:10 + 1, vs_nonabs = 1:10 *1.1 + .5)
DF <- tidyr::pivot_longer(data = DF, cols = vs_control:vs_nonabs, 
                          names_to = "TYPE", values_to = "Y")
ggplot(DF, aes(X, Y, group = TYPE, color = TYPE, linetype = TYPE)) +
  geom_line(size=1.2) +
  scale_x_continuous("False-Positive Rate") +
  scale_y_continuous("True-Positive Rate") +
  scale_color_manual(values=c("vs_control" = "black","vs_nonabs" = "red"), 
                     labels=c("vs Controls","vs Non-Absconds")) +
  scale_linetype_manual(breaks = c("vs_control", "vs_nonabs"),
                        values=c("solid","dashed"), labels=c("vs Controls","vs Non-Absconds")) +
  geom_segment(aes(x = 0, xend = 1, y = 0, yend = 1), color="black", linetype="dotted") + 
  theme(axis.text=element_text(size=20)) +
  theme(text = element_text(size=20,face="bold")) +
  theme(legend.title=element_blank()) +
  theme(legend.position=c(.8,.2))

Created on 2020-05-17 by the reprex package (v0.3.0)

1 Like

Hi @FJCC,

First, thanks so much for this. And yes, sorry about missing the data, rookie mistake. The data is attached here (ROC data).

My full code is here below. Grouping helps a lot, but the predictors are two variables, so not grouped into a single variable... does that make a difference?

rm(list=ls()) # clear out old junk
library(ggplot2)
library(haven)
library(tidyverse)
library(pROC)
library(randomForest)
newdat <- read_sav("/Users/baglolese/Desktop/ROC_sampledata.sav") #TOTAL

# Create a basic ROC plot
rocobj <- roc(newdat$Patient_type, newdat$BEAT_Total)
rocobj2 <- roc(newdat$Incident_Category, newdat$BEAT_Total)

## Fully format plot
gl <- ggroc(list(vs_control=rocobj, vs_nonabs=rocobj2), legacy.axes = TRUE) +
  geom_point(size=3) +
  geom_line(size=1.2) +
  scale_x_continuous("False-Positive Rate") +
  scale_y_continuous("True-Positive Rate") +
  scale_color_manual(values=c("vs_control" = "black","vs_nonabs" = "red"), 
                     labels=c("vs Controls","vs Non-Absconds")) +
  scale_linetype_manual(breaks = c("vs_control", "vs_nonabs"),
                        values=c("solid","dashed"), labels=c("vs Controls","vs Non-Absconds")) +
  geom_segment(aes(x = 0, xend = 1, y = 0, yend = 1), color="black", linetype="dotted") + 
  theme(axis.text=element_text(size=20)) +
  theme(text = element_text(size=20,face="bold")) +
  theme(legend.title=element_blank()) +
  theme(legend.position=c(.8,.2))
gl
  

Thanks !

I don't have this package so I am just guessing at what might work. Have you tried

gl <- ggroc(list(vs_control=rocobj, vs_nonabs=rocobj2), 
         legacy.axes = TRUE, aes = "linetype") +
  geom_point(size=3) +
  geom_line(size=1.2) +
  scale_x_continuous("False-Positive Rate") +
  scale_y_continuous("True-Positive Rate") +
  scale_color_manual(values=c("vs_control" = "black","vs_nonabs" = "red"), 
                     labels=c("vs Controls","vs Non-Absconds")) +
  scale_linetype_manual(breaks = c("vs_control", "vs_nonabs"),
                        values=c("solid","dashed"), labels=c("vs Controls","vs Non-Absconds")) +
  geom_segment(aes(x = 0, xend = 1, y = 0, yend = 1), color="black", linetype="dotted") + 
  theme(axis.text=element_text(size=20)) +
  theme(text = element_text(size=20,face="bold")) +
  theme(legend.title=element_blank()) +
  theme(legend.position=c(.8,.2))
gl

Try that with and without the breaks argument in scale_linetype_manual()

Wow. This is awesome, thank you! Got rid of the geom_point because I was playing with those too as an alternative.

Very much appreciated.

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.