Search code examples
rsurvminer

ggsurvplot function, risk table alignment problem


I have a trouble with risk table alignment with plot x aixs.

I would like to draw K-M curve starting at x = 0 and y = 0.

Below is code for my Figure.

library(survival)
library(survminer)
library(patchwork)

f <- survfit(Surv(time, status) ~ 1, data = lung)

Figure <- ggsurvplot(
  fit = f,
  fun = function(s) s * 100,
  pval = FALSE,
  conf.int = FALSE,
  cumcensor = FALSE,
  censor = FALSE,
  axes.offset = FALSE,
  size = 1.5,
  break.time.by = 365,
  risk.table = TRUE,
  risk.table.title = "No. at risk",
  risk.table.height = 0.18,
  risk.table.y.text = FALSE,
  risk.table.col = "strata",
  tables.theme = theme_cleantable(),
  palette = c("#0072B2"),
  ggtheme = theme_classic())

Figure$plot <- Figure$plot + 
  coord_cartesian(xlim = c(0, 800), clip = 'on', expand = FALSE)

Figure$table <- Figure$table + 
  coord_cartesian(xlim = c(0, 800), clip = 'on', expand = FALSE) +
  theme(legend.position = "null")

(Figure$plot / Figure$table) + plot_layout(heights = c(6,1))

In this setting, I would like to align plot x tick with risk table at x = 0 point.

enter image description here

I searched similar problems regarding risk table alignment, however there was no solution that did not edit x-axis starting point.

  1. when I change axes.offset = TRUE, first column of risk table is missing.
Figure <- ggsurvplot(
  fit = f,
  fun = function(s) s * 100,
  pval = FALSE,
  conf.int = FALSE,
  cumcensor = FALSE,
  censor = FALSE,
  axes.offset = TRUE,
  size = 1.5,
  break.time.by = 365,
  risk.table = TRUE,
  risk.table.title = "No. at risk",
  risk.table.height = 0.18,
  risk.table.y.text = FALSE,
  risk.table.col = "strata",
  tables.theme = theme_cleantable(),
  palette = c("#0072B2"),
  ggtheme = theme_classic())

Figure$plot <- Figure$plot + 
  coord_cartesian(xlim = c(0, 800), clip = 'on', expand = FALSE)

Figure$table <- Figure$table + 
  coord_cartesian(xlim = c(0, 800), clip = 'on', expand = FALSE) +
  theme(legend.position = "null")

(Figure$plot / Figure$table) + plot_layout(heights = c(6,1))

enter image description here

  1. I try to adjust axis.text.y option in risk table, however it doesn't work theme(axis.text.y = element_text(margin = margin(r = 1.5, unit = "cm")))
Figure <- ggsurvplot(
  fit = f,
  fun = function(s) s * 100,
  pval = FALSE,
  conf.int = FALSE,
  cumcensor = FALSE,
  censor = FALSE,
  axes.offset = TRUE,
  size = 1.5,
  break.time.by = 365,
  risk.table = TRUE,
  risk.table.title = "No. at risk",
  risk.table.height = 0.18,
  risk.table.y.text = FALSE,
  risk.table.col = "strata",
  tables.theme = theme_cleantable() +
theme(axis.text.y = element_text(margin = margin(r = 1.5, unit = "cm"))),
  palette = c("#0072B2"),
  ggtheme = theme_classic())

Figure$plot <- Figure$plot + 
  coord_cartesian(xlim = c(0, 800), clip = 'on', expand = FALSE)

Figure$table <- Figure$table + 
  coord_cartesian(xlim = c(0, 800), clip = 'on', expand = FALSE) +
  theme(legend.position = "null")

(Figure$plot / Figure$table) + plot_layout(heights = c(6,1))

enter image description here

So, ensuring that K-M curve starts at x = 0 and y = 0, could you help me to align plot x tick and risk table at x=0 point?

I believe there is a solution that adjust color indicator (blue line) in risk table or other options.

Thank you for your help

Write it with problems


Solution

  • Building on your second approach, i.e. using axes.offset=TRUE so that the table starts at 0 and adding some margin to the y axis text, you can set clip="off" to prevent that the table text gets clipped off and set the limits= for the x scale by overwriting the default scale_x_continuous to drop any labels which fall outside of the limits:

    library(survminer)
    library(ggplot2)
    library(survival)
    library(patchwork)
    library(ggtext)
    
    f2A <- survfit(Surv(time, status) ~ 1, data = lung)
    
    Figure <- ggsurvplot(
      fit = f2A,
      fun = function(s) s * 100,
      pval = FALSE,
      conf.int = FALSE,
      cumcensor = FALSE,
      censor = FALSE,
      axes.offset = TRUE,
      size = 1.5,
      xlim = c(0, 32),
      ylim = c(0, 110),
      xlab = "Follow-up duration (months)",
      ylab = "Progression free survival (%)",
      break.time.by = 3,
      risk.table = TRUE,
      risk.table.title = "No. at risk",
      risk.table.height = 0.18,
      risk.table.y.text = FALSE,
      risk.table.col = "strata",
      tables.theme = theme_cleantable(),
      palette = c("#0072B2"),
      ggtheme = theme_classic(),
    )
    
    Figure$plot <- Figure$plot +
      coord_cartesian(xlim = c(0, 32), expand = FALSE)
    
    Figure$table <- Figure$table +
      scale_x_continuous(limits = c(0, 32)) +
      coord_cartesian(xlim = c(0, 32), clip = "off", expand = FALSE) +
      theme(
        legend.position = "none",
        axis.text.y.left = ggtext::element_markdown(
          margin = margin(r = 20)
        )
      )
    
    (Figure$plot / Figure$table) + plot_layout(heights = c(6, 1))
    

    enter image description here