57
votes

In R, it is possible to hold a device, draw the picture, and then flush the device to render the graphics. This is useful for very complex plots with thousands of data points, color gradients etc since without holding, the device would be refreshed after each plotting operation. It works quite well.

However, once the plot is in place, any window operation such as a resize will cause the plot to be refreshed -- however, this time without holding and flushing the device, but plotting the plot elements one by one and refreshing the display each time. This is extremely annoying.

Clearly, I could call manually dev.hold before resizing the window, but this is not a real solution.

Is there a way of telling R that the device should be put on hold for operations such as resize?

1
To inhibit draw on resize, you can use dev.control("inhibit"), though you cannot then hold/redraw/flush it. I tried p <- recordPlot(), but replayPlot(p) (nor grDevices:::restoreRecordedPlot) does not seem to respect dev.hold(). Your answer may lie in the R source (mirrored by wch on github).r2evans
Thanks, while this does not solve my problem, it is a step towards a solution.January
also not a solution but I tend to plot to jpeg in rstudio since the plot window there is tiny. I keep the jpeg open in windows preview and repeated calls to the jpeg refresh it fairly rapidly.Dan Slone
I also recommend to not use the R graphics device for complex plots for exactly this reason, better use pdf, or a raster format such as png or jpeg if the plot is too complex.gdkrmr

1 Answers

2
votes

As indicated by Dan Slone and gdkrmr viable option is to use intermediate raster file to plot complex graphics.

The flow is the follows:

  1. Save plot to png file.
  2. Plot the image into the screen device.

After this there will be no problems with refreshing and resizing.

Please see the code below:

# plotting through png
plot.png <- function(x, y) {
  require(png)
  tmp <- tempfile()
  png(tmp, width = 1920, height = 1080)
  plot(x, y, type = "l")
  dev.off()
  ima <- readPNG(tmp)
  op <- par(mar = rep(0, 4))
  plot(NULL, xlim = c(0, 100), ylim = c(0, 100), xaxs = "i", yaxs = "i")
  rasterImage(ima, 0, 0, 100, 100, interpolate = TRUE)
  par(op)
  unlink(tmp)
}

t <- 1:1e3
x <- t * sin(t)
y <- t * cos(t)


# without buffering
# plot(x, y, type = "l")

# with buffering in high-res PNG-file
plot.png(x, y)

Ouput: picture