3

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().

Claus Wilke
  • 16,992
  • 7
  • 53
  • 104
user2338823
  • 501
  • 1
  • 3
  • 16

2 Answers2

2
graph_functions<- function(x) {
  plot(1:length(x),x)
  points(1:length(x),x^2)
  t<- recordPlot()
  return(t)
}
answer <- c(1:10)
library(cowplot)
plot_grid(graph_functions(answer),graph_functions(answer))

You could put the function inside the plot_grid() function and just store the parameters in the answer variable.

Jared C
  • 362
  • 7
  • 19
  • This was a MWE. In my code, graph_functions returns results with 3, 3 and 10 graphs in 3 different incantations. I need to use plot_grid( plotlist = ..., nrow=2,ncol=2) to plot the results. Take for example the case when I have 10 graphs returned. I want to display 4/4/2 graphs on separate pages. I can do plot_grid(graph_functions(answer)[1:4]),plot_grid(graph_functions(answer) [5:8]),plot_grid(graph_functions(answer)[9:10]) but each incantation calls the same function 3 times which is not efficient with time as the graphs are results of a computationally intensive regression.Any other way? – user2338823 Dec 01 '18 at 09:28
  • 1
    Maybe the answer from this question is what you're looking for? https://stackoverflow.com/questions/23767645/r-plot-without-showing-the-graphic-window – Jared C Dec 01 '18 at 09:35
  • You want me to use ggplot with theme_base ? I guess I should do that. It's much easier to compute a plot and not display it in ggplot. – user2338823 Dec 01 '18 at 10:00
  • of course ggplot would be an easy solution, but there is an answer there discussing how to hold onto regular plots using ?recordPlot – Jared C Dec 01 '18 at 10:04
  • @JaredC I think the question is how to record a plot without having the plot pop up or appear in a markdown document. I've provided an answer that does that. https://stackoverflow.com/a/53623172/4975218 – Claus Wilke Dec 05 '18 at 22:57
1

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)

Claus Wilke
  • 16,992
  • 7
  • 53
  • 104