kassambara / survminer

Survival Analysis and Visualization
https://rpkgs.datanovia.com/survminer/
509 stars 164 forks source link

Add a customized text to each panel in a ggsurvplot_facet plot #617

Open Antoine-KDA opened 1 year ago

Antoine-KDA commented 1 year ago

Hello, Thank you for this wonderful package. I was wondering if there is a way to add different customized text individually to each panel of the plot yielded by ggsurvplot_facet. I have tried : datHRa <- data.frame(hr = c("label= 4.3 (2.0; 9.0)", "HRa= 1.4 (1.0; 2.0)", "HRa= 2.2 (1.7; 2.7)", "HRa= 2.0 (1.3; 2.9)"), x=c(4,4,4,4), y=c(0.57, 0.57, 0.57, 0.57))

First case

facplot+ggplot2::annotate("text",x=4, y=0.57, label = list(c("HRa= 4.3 (2.0; 9.0)", "HRa= 1.4 (1.0; 2.0)", "HRa= 2.2 (1.7; 2.7)")), size = 4)

Second case

facplot+geom_text(data = datHRa, mapping = aes(x = x, y=y, label=hr))

Where facplot is the plot object created by ggsurvplot_facet with ncol=2, nrow=2.

Actual behavior

Both of the results (first and second cases) are weird, all the annotations are displayed at once at each coordinate and repeated identically for the 4 panels in the plot.

image image

Expected behavior

What I wanted was one annotation per panel at the given coordinate. The annotations are different for each panel. Like in this example with ggplot dat_text <- data.frame( label = c("4 cylinders", "6 cylinders", "8 cylinders"), cyl = c(4, 6, 8), x = c(20, 27.5, 25), y = c(4, 4, 4.5) )

p + geom_text( data = dat_text, mapping = aes(x = x, y = y, label = label) )

image

Steps to reproduce the problem

I am sorry I could not share the original data.

session_info()

sessionInfo() R version 4.2.2 (2022-10-31 ucrt) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows 10 x64 (build 22621)

Matrix products: default

attached base packages: [1] stats graphics grDevices datasets utils methods base

other attached packages: [1] ggrepel_0.9.2 survminer_0.4.9 ggpubr_0.5.0 ggplot2_3.4.0 haven_2.5.1 survival_3.4-0 [7] magrittr_2.0.3 dplyr_1.0.10

loaded via a namespace (and not attached): [1] zoo_1.8-11 tidyselect_1.2.0 xfun_0.36 purrr_1.0.1 splines_4.2.2 lattice_0.20-45
[7] carData_3.0-5 colorspace_2.1-0 vctrs_0.5.2 generics_0.1.3 utf8_1.2.2 survMisc_0.5.6
[13] rlang_1.0.6 gridtext_0.1.5 pillar_1.8.1 glue_1.6.2 withr_2.5.0 lifecycle_1.0.3
[19] stringr_1.5.0 commonmark_1.8.1 munsell_0.5.0 ggsignif_0.6.4 gtable_0.3.1 ggsci_2.9
[25] labeling_0.4.2 knitr_1.42 forcats_0.5.2 markdown_1.4 fansi_1.0.4 Rcpp_1.0.10
[31] broom_1.0.3 xtable_1.8-4 renv_0.16.0 scales_1.2.1 backports_1.4.1 abind_1.4-5
[37] farver_2.1.1 km.ci_0.5-6 gridExtra_2.3 hms_1.1.2 stringi_1.7.12 rstatix_0.7.1
[43] KMsurv_0.1-5 cowplot_1.1.1 grid_4.2.2 cli_3.6.0 tools_4.2.2 ggeasy_0.1.3
[49] tibble_3.1.8 tidyr_1.3.0 car_3.1-1 pkgconfig_2.0.3 ellipsis_0.3.2 Matrix_1.5-1
[55] xml2_1.3.3 data.table_1.14.6 R6_2.5.1 ggtext_0.1.2 compiler_4.2.2

# please paste here the result of
devtools::session_info()
sebastian-gerdes commented 1 year ago

Hello Antoine,

maybe the following code snippets help. However, I am not sure, if is intended use of the survminer package.

library('survival')
library('tidyverse')
library('survminer')

text_to_add <- 
  tribble(~ sex, ~ text, ~ x, ~ y, 
          0, 'Some text', 1000, 0.1,
          1, 'Some other text', 1000, 0.1)

fit <- survfit(Surv(time, status) ~ sex, data = colon)
gg <- ggsurvplot(fit)
gg$plot + facet_wrap(vars(sex)) + theme_gray() + 
  geom_label(aes(x = x, y = y, label = text),
             text_to_add, inherit.aes = FALSE)

unnamed-chunk-6-1

If you want to avoid the change of the color and suppress the legend:

gg <- ggsurvplot(fit, palette = c('black', 'black'))
gg$plot + facet_wrap(vars(sex)) + theme_gray() + 
  geom_label(aes(x = x, y = y, label = text),
             text_to_add, inherit.aes = FALSE) +
  theme(legend.position = "none")

unnamed-chunk-7-1

It seems a bit hacky to me, but maybe it works for you.