You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ggsurvplot风险表与K-M曲线X轴对齐问题求助

解决ggsurvplot绘制K-M曲线时风险表与X轴对齐问题

需求

实现K-M曲线从(0,0)位置起始,同时让风险表的x=0位置与图表X轴刻度完全对齐。

初始代码(存在对齐问题)

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))

尝试过的无效方法

方法1:设置axes.offset = TRUE

风险表第一列直接缺失,无法实现对齐:

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))

方法2:调整风险表axis.text.y边距

对X轴对齐无任何效果:

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))

有效解决方案

核心是让绘图区域和风险表的X轴缩放参数完全统一,同时保留曲线从(0,0)起始的设置:

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, # 确保曲线从(0,0)起始
  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(legend.position = "none"), # 提前隐藏图例
  palette = c("#0072B2"),
  ggtheme = theme_classic()
)

# 统一设置绘图和风险表的X/Y轴范围与扩展参数,确保对齐
Figure$plot <- Figure$plot + 
  scale_x_continuous(limits = c(0, 800), expand = c(0, 0)) +
  scale_y_continuous(limits = c(0, 100), expand = c(0, 0)) # 强制Y轴从0起始

Figure$table <- Figure$table + 
  scale_x_continuous(limits = c(0, 800), expand = c(0, 0))

# 组合图形并设置高度比例
(Figure$plot / Figure$table) + plot_layout(heights = c(6,1))

原理说明

  1. axes.offset = FALSE:确保K-M曲线的起点直接贴合(0,0)坐标,不产生偏移。
  2. 替换coord_cartesian为scale_x_continuous:前者仅限制显示范围,后者直接定义轴的实际范围和扩展量,让绘图区域和风险表的X轴起点、刻度完全匹配。
  3. 统一expand = c(0,0):取消X轴两端的默认留白,确保x=0位置完全对齐。

内容的提问来源于stack exchange,提问作者Hyun Seok Kwak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 04:50:55