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'的效果:
解决方案
核心思路是:生存图严格限制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))
关键调整说明
- 生存图部分:使用
coord_cartesian(xlim = c(-50, time_cutoff), clip = 'on')严格限制x轴范围,确保生存曲线仅绘制到终止时间,且裁剪所有超出该范围的元素,保证右侧标注与曲线末端对齐。 - 风险表部分:
- 通过
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
相关产品推荐
相关产品推荐

