Convert a ggsurvplot object to a grob

I have four plots, three of them ggsurvplot objects, that I need to compose into a single 2x2 facet plot. I am blocked because it appears that there is no automatic way to convert a ggsurvplot to a grob, as appears to be required for me to combine them using gridextra. The four plots are also saved as pdf figures, but these also seem not to be importable as grobs. They should all be vector graphics.
Any suggestions as to how I can convert the ggsrurvplot objects into grobs?

Try the {patchwork} package—no conversion needed.

Thanks for the suggestion, technocrat. Unfortunately patchwork seems to have the same problem that other approaches that depend on blobification have. Evidently despite the graphics being based on ggplot, the final ggsurvplot object is not a legitimate ggplot object. I suspect that the ggsurvplot programmers have used a non-(ggplot) standard method to combine the survival plot and the "at risk" table.
That the error code recognizes a .ggsurv method suggests that R recognizes a different and incompatible implementation of '+' for ggplot and ggsurvplot objects. But I can't find anything else in the patchwork package that addresses ggsurvplot objects. Have I missed anything in the patchwork package?

plot1 and plot2 are two ggsurvplots. Plot4 is a standard ggplot object.

plot1 + plot2 +labs(subtitle = 'test')
Error in plot1 + plot2 : non-numeric argument to binary operator
In addition: Warning message:
In +.ggsurv(plot1, plot2) :
Incompatible methods ("", "+.ggsurv") for "+"

plot1 + plot4 +labs(subtitle = 'test')
Error in plot1 + plot4 : non-numeric argument to binary operator
In addition: Warning message:
Incompatible methods ("+.ggsurv", "") for "+"

The code below won't reprex properly. It extracts the ggplot object for separate plotting, which can be patchworked in the normal way. The tables have to be plotted separately or could, I suppose, be rendered as an annotation only plot separately and patchworked.


# from documentation
# Fit survival curves
fit<- survfit(Surv(time, status) ~ sex, data = lung)

# Basic survival curves 
# NOTE risk.table = FALSE
ggsurv <- ggsurvplot(fit, data = lung, risk.table = FALSE,
                     main = "Survival curves",
                     submain = "Based on Kaplan-Meier estimates",
                     caption = "created with survminer"

# duplicate for multiple plotting
ggsurv2 <- ggsurvplot(fit, data = lung, risk.table = FALSE,
                     main = "Survival curves",
                     submain = "Based on Kaplan-Meier estimates",
                     caption = "created with survminer"

# Extract ggplot objects
a <- ggsurv$plot
b <- ggsurv2$plot

# Extract tables
atab <- ggsurv$data.survtable
btab <- ggsurv$data.survtable

# plot graphs
a / b

# display table separately
1 Like

Yes. This is what I suspected. The ggsurv$plot object is a ggplot object and is, therefore grobable and works fine. But the ggsurvplot object is basically a list of a ggplot object and a data.frame. This is what is giving patchwork (and all the other methods for combining grobs) indigestion.

I was working on a similar combined survival curve/at risk table function several years ago. But I created the "at risk" table as a grob and then combined the plot grob with the " at risk" grob. So the combination was also a grob. The survminer version evidently doesn't do this. I gave up on my version when survminer was released, as it seemed to do everything that I needed at the time and I didn't have the time to support my own package. I suppose that I'll have to go back and see what I did. I suppose that it never occurred to the survminer authors that someone would want to put several separate survival plots with risk tables into a trellis composite.

Thanks for your examination of this issue. I have figured out a kludge creating a Word table and pasting the SVG plots into the table cells. Cumbersome, but it works if one compiles a Rmd to pdf, saves the pdf plots and converts them to SVG. So it is no longer urgent for me. I'll see if I have the time to fix this problem.

1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.