Search code examples
rcowplot

Return graph from function without plotting it


I want to write function which returns a graph but it should not plot the graph. It should only plot the graph when I ask it to.

Here is a MWE.

graph_functions <- function(x) {
  plot(1:length(x), x)
  points(1:length(x), x^2)
  t <- recordPlot()
  return(t)
}

answer <- graph_functions(1:10)

library(cowplot)
plot_grid(answer, answer)

In the above code I do not want it to plot the graph when I first compute the answer by calling graph_functions(1:10). I only want it to plot the graph when I use plot_grid().


Solution

  • You can open a null device and render to it. Note that if you're using cowplot with base-R graphics, you should upgrade to the development version, with devtools::install_github("wilkelab/cowplot"). It provides much improved handling of base-R graphics.

    graph_functions <- function(x) {
      cur_dev <- grDevices::dev.cur()   # store current device
      pdf(NULL, width = 6, height = 6)  # open null device
      grDevices::dev.control("enable")  # turn on recording for the null device
      null_dev <- grDevices::dev.cur()  # store null device
    
      # make sure we always clean up properly, even if something causes an error
      on.exit({
        grDevices::dev.off(null_dev)
        if (cur_dev > 1) grDevices::dev.set(cur_dev) # only set cur device if not null device
      })
    
      # plot
      plot(1:length(x), x)
      points(1:length(x), x^2)
      recordPlot()
    }
    
    answer1 <- graph_functions(1:10)
    answer2 <- graph_functions(1:20)
    cowplot::plot_grid(answer1, answer2)
    

    Created on 2018-12-04 by the reprex package (v0.2.1)