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

ggsurvplot生存图右侧标注长标签时风险表文本截断问题

解决ggsurvplot指定终止时间后风险表文本截断的问题

问题背景

在使用ggsurvplot绘制生存曲线时,需要指定终止时间time_cutoff,同时在生存图右侧标注曲线末端的生存比例。但设置xlim=c(-50, time_cutoff)后,风险表(number-at-risk table)最右侧的数值被截断——实际数值为20、21,却仅显示开头的2、2。

问题现象:
标注后风险表截断效果:
标注后风险表截断效果

曾尝试两种方案,但均存在缺陷:

  • 扩大x轴范围至time_cutoff+50:风险表文本不再截断,但生存曲线会延伸至该范围,且右侧标注无法与曲线末端对齐。
  • 仅给风险表设置clip='off':会显示超出time_cutoff的额外风险数值,不符合需求。

仅开启风险表clip='off'的效果:
clip='off'后的风险表

解决方案

核心思路是:生存图严格限制x轴范围以保证曲线和标注对齐,风险表通过调整x轴扩展参数、裁剪设置和边距,在不显示额外数值的前提下完整展示文本。

修改后的完整代码

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

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

# 初始化生存图
my_plot <- ggsurvplot(fit, data = lung,
                      risk.table = TRUE,
                      tables.height = 0.2,
                      break.x.by = 100,
                      ggtheme = theme_bw()              
)

time_cutoff <- 400
xticks <- c(0, 100, 200, 300, 400)

# 获取终止时间点的生存比例并创建右侧标签
survs <- summary(fit, times = time_cutoff)$surv
labels <- paste(round(survs*100), '% this label is really long', sep='')

# 修饰生存图:限制x轴范围到终止时间,添加右侧标注
my_plot$plot <- my_plot$plot + 
  coord_cartesian(ylim = c(0,1), xlim = c(-50, time_cutoff), clip = 'on', expand = FALSE) +
  scale_x_continuous(name = NULL, breaks = xticks) +
  scale_y_continuous(
    name = NULL, 
    sec.axis = sec_axis(~., name = NULL, breaks = survs, labels = labels)
  ) +
  theme(
    panel.border = element_blank(),
    axis.line.y.left = element_line(color = 'black'),
    axis.line.x.bottom = element_line(color = 'black'),
  )

# 修饰风险表:解决文本截断问题,同时不显示额外数值
table_ylim <- ggplot_build(my_plot$table)$layout$panel_params[[1]]$y.range
my_plot$table <- my_plot$table + 
  scale_x_continuous(
    name = NULL, 
    breaks = xticks, 
    limits = c(-50, time_cutoff), 
    expand = c(0, 0.1) # 右侧扩展空间,避免文本截断
  ) +
  coord_cartesian(ylim = table_ylim, clip = 'off') + # 允许文本超出x轴范围显示
  theme(
    panel.border = element_blank(),
    plot.margin = margin(5, 25, 5, 5) # 增加右侧边距,适配长文本
  )

# 组合绘图
(my_plot$plot / my_plot$table) + plot_layout(heights = c(3,1))

关键调整说明

  1. 生存图部分:使用coord_cartesian(xlim = c(-50, time_cutoff), clip = 'on')严格限制x轴范围,确保生存曲线仅绘制到终止时间,且裁剪所有超出该范围的元素,保证右侧标注与曲线末端对齐。
  2. 风险表部分:
    • 通过scale_x_continuous(limits = c(-50, time_cutoff), breaks = xticks)控制x轴的显示范围和刻度,避免出现超出终止时间的额外风险数值。
    • 设置expand = c(0, 0.1)给x轴右侧留出额外空间,让完整的风险数值能显示。
    • 启用clip='off'允许文本显示在x轴范围之外,但由于已指定刻度,不会出现多余数值。
    • 调整plot.margin增加右侧边距,确保长文本不会被画布边缘截断。

类似的短标签截断问题,可通过相同的x轴扩展和裁剪设置解决,本次针对长标签额外调整了边距适配。

内容的提问来源于stack exchange,提问作者Gordon Lemmon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 09:35:23