3

I am trying to plot several Kaplan Meijer curves in a grid with a shared legend in R. Here (common legend in arrange_ggsurvplots) ggsurvplot_facet is advised. However, in my case, every plot is based on a different fit using different variables, so ggsurvplot_facet is (at least in my understanding) not applicable here. Please see my data and script below. Is there a way to have these plots arranged while sharing one legend? I've tried working with ggarrange and grid_arrange_shared_legend, but I couldn't get it to work with ggsurvplot objects.

library(survival)
library(survminer)

data_km <- data.frame(DaysToFirstDetectByBird = c(16.88, 50.17, 1.14, 22.46, 9.95, 4.64, 1.08, 7.06, 1.86, 0.00, 1.11, 2.87, 3.63, 29.15, 0.31, 13.89, 2.16, 2.24, 5.93, 0.12, 0.92, 0.06, 0.08, 0.32, 1.23, 19.06, 8.09, 0.17, 16.04, 4.86, 4.11, 2.94, 0.06, 5.69, 4.87),
           FirstDetectByBirdEvent = c(1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1),
           DaysToFirstDetectByMammal = c(1.63, 6.47, 1.44, 1.62, 1.22, 1.13, 2.22, 3.43, 10.66, 2.37, 20.83, 0.64, 1.09, 1.46, 0.49, 0.72, 0.90, 0.59, 6.05, 10.43, 3.04, 0.68, 0.53, 27.47, 0.93, 2.57, 0.46, 0.68, 2.61, 5.32, 0.69, 0.22, 0.42, 0.51, 0.50),
           FirstDetectByMammalEvent = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
           OcGroup = c("Open", "Open", "Open", "Open", "Open", "Open", "Open", "Open", "Open", "Open", "Open", "Open", "Open", "Open", "Open", "Open", "Forest", "Forest", "Forest", "Forest", "Forest", "Forest", "Forest", "Forest", "Forest", "Forest", "Forest", "Forest", "Forest", "Forest", "Forest", "Forest", "Forest", "Forest", "Forest"))

# plotA
SurvFit_DetectionBird <- survfit(Surv(DaysToFirstDetectByBird, FirstDetectByBirdEvent) ~ OcGroup, data = data_km)
plot_DetectionBird <- ggsurvplot(SurvFit_DetectionBird)
plot_DetectionBird$plot <- plot_DetectionBird$plot + labs(title = "A")

# plotB
SurvFit_DetectionMammal <- survfit(Surv(DaysToFirstDetectByMammal, FirstDetectByMammalEvent) ~ OcGroup, data = data_km)
plot_DetectionMammal <- ggsurvplot(SurvFit_DetectionMammal)
plot_DetectionMammal$plot <- plot_DetectionMammal$plot + labs(title = "B")

# arrange plots
plots <- list(plot_DetectionBird, plot_DetectionMammal)
res <- arrange_ggsurvplots(plots, print = FALSE,
                           ncol = 1, nrow = 2)

ggsave("~/Desktop/survplots_test.pdf", res)

enter image description here

Peter
  • 343
  • 5
  • 17
  • have a look at the `patchwork` library. Something like `p1 + p2 + plot_layout( guides = 'collect')` – Richard Telford Jan 28 '20 at 14:43
  • Thanks for the tip. I have read the documentation and experimented with it. However, I constantly get the error message `Error in p + e2 : non-numeric argument to binary operator In addition: Warning message: In '+.ggsurv'(plot_DetectionBird, plot_ScavBird) : Incompatible methods ("+.gg", "+.ggsurv") for "+"` It seems to not work with ggsurv objects. – Peter Jan 28 '20 at 15:33
  • 1
    How about just hiding the second legend? `plot_DetectionMammal <- ggsurvplot(SurvFit_DetectionMammal, legend = "none")` – Ben Jan 28 '20 at 16:52
  • 1
    That would definitely be a good and simple solution. However, for my real data I have to plot 6 graphs, so the one legend would be uncentered and the graphs unsymmetrical. The clue was to extract the ggplot object from the "ggsurvplot" object. – Peter Jan 29 '20 at 07:48

1 Answers1

3

You can use patchwork package, but first you need to extract the ggplot object from the "ggsurvplot" object

library(patchwork)
(plot_DetectionBird$plot + plot_DetectionMammal$plot) / guide_area() + 
  plot_layout( guides = 'collect')
Richard Telford
  • 9,558
  • 6
  • 38
  • 51