Gordon Lemmon
Gordon Lemmon

Reputation: 75

ggsurvplot risk table misaligned after annotating to the right of survival graph

I want to add survival percentages at the end of the curves. Doing so leads to the risk table not lining up with the graph (the graph width is reduced relative to the risk table width). Risk table and graph are not aligned

Code to reproduce the graph:

library(survival)
library(survminer)

fit<- survfit(Surv(time, status) ~ sex, data = lung)

ggsurvplot(fit, data = lung,

  risk.table = TRUE,
  tables.height = 0.2,
  ggtheme = theme_bw() # Change ggplot2 theme
)

time_cutoff = 600
survs = summary(fit, times=time_cutoff)$surv
labels = paste(round(survs*100), '%', sep='')
  
my_plot$plot <- my_plot$plot + coord_cartesian(ylim=c(0,1), xlim = c(0,time_cutoff), clip = 'on', expand=FALSE)
my_plot$plot <- my_plot$plot + scale_y_continuous(name=NULL, sec.axis=sec_axis(~., name=NULL, breaks =  survs, labels= labels)) 
my_plot

Upvotes: 1

Views: 1497

Answers (2)

Gordon Lemmon
Gordon Lemmon

Reputation: 75

Thanks to Allen Cameron's answer for getting me 95% to the answer. Adding to his response, I have to modify the table the same way we modified the survival graph:

library(survival)
library(survminer)

fit<- survfit(Surv(time, status) ~ sex, data = lung)

# Customized survival curves
my_plot = ggsurvplot(fit, data = lung,
 # Add p-value and tervals
 risk.table = TRUE,
 tables.height = 0.2,
 ggtheme = theme_bw() # Change ggplot2 theme
)

time_cutoff = 600
survs = summary(fit, times=time_cutoff)$surv
labels = paste(round(survs*100), '%', sep='')
  
my_plot$plot <- my_plot$plot + coord_cartesian(ylim=c(0,1), xlim = c(-50,time_cutoff), clip = 'on', expand=FALSE)
my_plot$plot <- my_plot$plot + scale_y_continuous(name=NULL, sec.axis=sec_axis(~., name=NULL, breaks = survs, labels= labels)) 
table_ylim = ggplot_build(my_plot$table)$layout$panel_params[[1]]$y.range
my_plot$table <- my_plot$table + coord_cartesian(ylim=table_ylim, xlim = c(-50,time_cutoff), clip = 'on', expand=FALSE)
library(patchwork)
(my_plot$plot / my_plot$table) + plot_layout(heights = c(3,1))

survival plot with number at risk table

Upvotes: 1

Allan Cameron
Allan Cameron

Reputation: 173793

There are a few ways to do this. Perhaps the easiest is to add a coord_cartesian to the my_plot$table object, then draw the plot and table with patchwork, which will align the panels

library(survival)
library(survminer)

fit<- survfit(Surv(time, status) ~ sex, data = lung)

my_plot <- ggsurvplot(fit, data = lung,
           risk.table = TRUE,
           tables.height = 0.2,
           ggtheme = theme_bw() 
)

time_cutoff = 600
survs = summary(fit, times=time_cutoff)$surv
labels = paste(round(survs*100), '%', sep='')

my_plot$plot <- my_plot$plot + 
  coord_cartesian(ylim = c(0, 1), 
                  xlim = c(0, time_cutoff), 
                  clip = 'on') + 
  scale_y_continuous(name = NULL, 
                     sec.axis = sec_axis(~., name = NULL, breaks = survs, 
                                         labels = labels)) 

my_plot$table <- my_plot$table +
  coord_cartesian(xlim = c(0, time_cutoff), 
                  clip = 'on')

library(patchwork)

(my_plot$plot / my_plot$table) + plot_layout(heights = c(3, 1))

Created on 2022-12-08 with reprex v2.0.2

Upvotes: 3

Related Questions