How can I insert a gap into y-axis in ggsurvplot?

Viewed 652

I am analysing this data for survival analysis. Below you may find the code, the dataframe and plots that are produced by that. Those plots differ only by that the Y-axis in the second one is truncated. However, it is good practice (if we accept that the Y-axis is allowed to be truncated) to insert there a "gap-sign". Is there any way how to insert it to the plot? I have so far found none. Thank you :-)

This is my code:

ggsurvplot(fit = fit, data = dat, pval = TRUE, 
       palette = "lancet", 
       linetype = c("solid", "dotted"),
       risk.table = F,
       break.time.by = 365, 
       title = "5-years death-censored graft survival",
       xlab = "Days from transplantation",
       ylab = "Survival (%)",
       xlim = c(0, 1825),
       ylim = c(0.5,1),
       pval.coord = c(5,0.6),
       censor.shape = 124,
       legend.labs = c("Control group", "TMA group"),
       legend.title = "",
       surv.scale = "percent")

This is the data frame.

"","Group","STATUS_surv","TIME_surv_5yr"
"1",1,1,1385
"2",1,1,212
"3",1,0,739
"4",1,1,571
"5",1,1,115
"6",1,0,1825
"7",1,1,1241
"8",1,0,1825
"9",1,0,1825
"10",1,1,59
"11",1,0,1825
"12",1,0,1825
"13",1,0,1623
"14",1,0,1825
"15",1,1,103
"16",1,0,1825
"17",1,0,1825
"18",1,1,1586
"19",1,1,75
"20",1,0,1825
"21",1,0,1825
"22",1,1,488
"23",1,0,1825
"24",1,0,1825
"25",1,0,1825
"26",1,0,1825
"27",1,0,1791
"28",1,1,977
"29",1,0,1622
"30",1,1,485
"31",1,1,166
"32",1,0,1189
"33",1,0,1093
"34",1,0,678
"35",1,0,676
"36",1,1,110
"37",1,0,480
"38",1,1,19
"39",1,0,312
"40",1,0,1825
"41",1,1,554
"42",1,0,1825
"43",1,1,62
"44",1,1,459
"45",1,1,79
"46",1,1,136
"47",1,1,1640
"48",1,1,675
"49",1,0,1825
"50",1,1,1612
"51",1,0,1825
"52",1,0,1302
"53",1,1,17
"54",1,1,256
"55",1,0,1825
"56",1,0,1825
"57",1,1,1199
"58",1,0,1825
"59",1,0,1825
"60",1,1,42
"61",1,0,1825
"62",1,0,1825
"63",1,0,1825
"64",1,1,1412
"65",1,1,200
"66",1,0,1825
"67",1,1,0
"68",1,0,1469
"69",1,0,984
"70",1,0,908
"71",1,0,846
"72",1,0,784
"73",1,0,667
"74",1,0,569
"75",1,1,107
"76",1,0,123
"77",1,0,80
"78",1,0,1825
"79",1,1,1244
"80",1,0,501
"81",1,0,1361
"82",1,0,1825
"83",1,1,56
"84",1,0,1825
"85",1,1,959
"86",1,0,1825
"87",1,1,22
"88",1,0,1825
"89",1,1,2
"90",1,1,1631
"91",1,0,53
"92",1,0,1825
"93",1,0,23
"94",0,0,1825
"95",0,0,1825
"96",0,0,642
"97",0,0,1825
"98",0,0,1825
"99",0,0,1825
"100",0,0,325
"101",0,0,1825
"102",0,0,1825
"103",0,0,1825
"104",0,0,1825
"105",0,0,1825
"106",0,0,955
"107",0,0,1825
"108",0,1,7
"109",0,1,6
"110",0,0,1570
"111",0,1,562
"112",0,0,1825
"113",0,0,1825
"114",0,0,1825
"115",0,0,1825
"116",0,0,1825
"117",0,0,1825
"118",0,0,1825
"119",0,1,51
"120",0,0,1791
"121",0,0,1672
"122",0,0,1622
"123",0,0,1603
"124",0,0,1342
"125",0,0,1189
"126",0,0,1093
"127",0,0,678
"128",0,0,676
"129",0,1,152
"130",0,0,480
"131",0,0,467
"132",0,0,312
"133",0,1,1080
"134",0,0,1825
"135",0,0,1825
"136",0,1,411
"137",0,1,1011
"138",0,0,1825
"139",0,0,1825
"140",0,0,1825
"141",0,1,1003
"142",0,0,1825
"143",0,0,1825
"144",0,1,438
"145",0,0,1825
"146",0,0,1825
"147",0,0,1825
"148",0,0,1698
"149",0,0,1825
"150",0,0,1825
"151",0,0,1825
"152",0,0,1825
"153",0,0,1825
"154",0,0,1825
"155",0,1,17
"156",0,0,1825
"157",0,0,1825
"158",0,0,1246
"159",0,0,1825
"160",0,0,1825
"161",0,0,1469
"162",0,0,984
"163",0,0,908
"164",0,0,846
"165",0,0,784
"166",0,0,667
"167",0,0,569
"168",0,0,194
"169",0,0,123
"170",0,0,80
"171",0,0,1825
"172",0,0,1825
"173",0,0,1078
"174",0,0,1361
"175",0,0,1825
"176",0,0,1386
"177",0,0,1825
"178",0,0,1825
"179",0,0,1825
"180",0,0,149
"181",0,0,1825
"182",0,0,1825
"183",0,0,1825
"184",0,0,54
"185",0,0,1825
"186",0,0,23

Plot 1 - with whole Y-axis:

Plot 2 - with truncated Y-axis

1 Answers

You didn't show us how you got fit, but the following seems to match your output:

library(survival)
library(survminer)

dat <- within(dat, surv <- Surv(time = TIME_surv_5yr, event = STATUS_surv))
fit <- survfit(surv ~ Group, data = dat)

Now, I will make sure that I can recreate your plot:

p <- ggsurvplot(fit = fit, data = dat, pval = TRUE, 
       palette = "lancet", 
       linetype = c("solid", "dotted"),
       risk.table = F,
       break.time.by = 365, 
       title = "5-years death-censored graft survival",
       xlab = "Days from transplantation",
       ylab = "Survival (%)",
       xlim = c(0, 1825),
       ylim = c(0.5,1),
       pval.coord = c(5,0.6),
       censor.shape = 124,
       legend.labs = c("Control group", "TMA group"),
       legend.title = "",
       surv.scale = "percent")

p

enter image description here

I think it is questionable whether it is better to put a gap in the y axis as opposed to just labelling it clearly. The original author of ggplot2, on which ggsurvplot is built, is not a fan, and that is one of the reasons why this type of axis is not natively possible in ggplot (or, by extension, in ggsurvplot). However, I see you are using The Lancet's styling, and it is the case that survival curves are sometimes plotted that way in The Lancet , so rather than suggesting you just set the y axis scale to be between 0 and 100 (which I happen to think would be the most honest way to present this data set), I will show you how to "manually" create a gapped y axis.

The steps you need to take are

  1. Access the underlying ggplot object in your ggsurv plot using the $plot member.
  2. Change the y axis labels by adding a scale_y_continuous call
  3. Add a coord_cartesian call where you turn off clipping and set the x axis limits
  4. Remove the y axis line using theme(axis.line.y = element_blank())
  5. Draw in a dummy axis line using annotation_custom
  6. Draw a white rectangle over the area of the y axis you wish to turn into a gap, again using annotation_custom
  7. Finally, draw two diagonal lines at the appropriate points on the y axis using annotation_custom:
p$plot + 
  scale_y_continuous(limits = c(0.4, 1), 
                     labels = scales::percent(c(0, 0.6, 0.8, 1))) +
  coord_cartesian(clip = "off", xlim = c(0, 1825)) +
  annotation_custom(grid::linesGrob(),
                    xmin = -90, xmax = -90, ymin = 0.37, ymax = 1) +
  annotation_custom(grid::rectGrob(gp = grid::gpar(fill = "white", col = NA)),
                    xmin = -120, xmax = 0, ymin = 0.45, ymax = 0.50) +
  annotation_custom(grid::linesGrob(),
                    xmin = -110, xmax = -70, ymin = 0.49, ymax = 0.51) +
  annotation_custom(grid::linesGrob(),
                    xmin = -110, xmax = -70, ymin = 0.44, ymax = 0.46) +
  theme(axis.line.y = element_blank())

enter image description here

Related