Jørgen K. Kanters Jørgen K. Kanters - 1 month ago 22
R Question

ggsurv legends and line thickness

I have some problems with the ggsurv function in ggplot.

I want to control the order of appearance with legends and the line style.

I can see that others have similar problems but I dont understand the solution

Using the standard lung data my problem is as

library(GGally)
library(survival)
data(lung)
surv1 <- survfit(Surv(time,status) ~ sex, data = lung)
p1 <- ggsurv(surv1, lty.est=c(1,2), surv.col=c("black", "red" ))
p1 <- p1 + scale_colour_discrete(name = 'sex', breaks = c(1,2), labels=c('XX','XY'))
p1


Here I would have expected the standard values in the legend replaced with XX and XY. But I get a duplicated legend instead. One with correct line attributes but wrong names and color. Another with correct names and color but wrong line attributes.

I have tried to insert

p1 <- p1 + guides(colour = FALSE)


but that removes the wrong part of the legend

What do I not understand?

Thanks to cuttlefish's comments a solution is:

library(GGally)
library(survival)
data(lung)
surv1 <- survfit(Surv(time,status) ~ sex, data = lung)
p1 <- ggsurv(surv1, lty.est=c(1,2), surv.col=c("black", "red" ))
p1 <- p1 + scale_colour_discrete(name = 'sex', breaks = c(1,2), labels=c('XX','XY'))
p1 <- p1 + guides(linetype = F, colour = guide_legend(override.aes = list(linetype = c(2,1))))
p1


I can understand that the override.aes manually set the line types used in the legend. I am not fully sure what the linetype = F actually does, but it works!

A second question. How do You manually set the thickness of the lines (both in the graph and the legend)

Adding

p1 <- p1 + geom_line(size=2)


does not work. It draws ugly black lines which not are fully aligned with the orignal ones.

Answer

You can combine legends by using both scale_color and scale_linetype, making sure the two scales have the same name and labels. Looks like the colors need to be defined again in scale_color_manual.

You can add the lines via geom_step, setting the correct colors and line types by using the variable group present from the ggsurv object. The downside of this is that a second set of lines is drawn on top of the original so the result doesn't necessarily look particularly nice.

ggsurv(surv1, lty.est=c(1,2), surv.col=c("black", "red" )) +
    scale_color_manual(name = "sex", values = c("black", "red"), labels = c("XX", "YY")) +
    scale_linetype_discrete(name = "sex", labels = c("XX", "YY")) +
    geom_step(size = 1, aes(color = group, linetype = group))

There's a point when you want to change enough things that it is worth building the graph "by hand" with ggplot2. This can be done for survival models by using fortify from ggfortify on the model object.

library(ggfortify)      
library(ggplot2)        
plot.data = fortify(surv1, surv.connect = TRUE)

ggplot(plot.data, aes(time, surv, color = strata)) +
    geom_step(aes(linetype = strata), size = 1) +
    geom_point(data = subset(plot.data, n.censor > 0), shape = 3, color = "red") +
    scale_color_manual(name = "sex", labels = c("XX", "YY"), values = c("black", "red")) +
    scale_linetype_discrete(name = "sex", labels = c("XX", "YY")) +
    labs(y = "Survival", x = "Time")