Kun Ren
Kun Ren

Reputation: 5013

How to save plots automatically to png?

Is it possible that plots are automatically saved to a folder in png format in the following manner?

  1. A new png file is created at each call of plot.new()
  2. The file is updated at each update of graphics (when e.g. points(), lines(), rect() are called) so that whenever the plot is updated, the file is updated too (without having to close the device by dev.off())

If this is possible, the following code should work as supposed:

plot(rnorm(100))
# create a new png file (e.g. plot-1.png) and the graphics is output to the file

plot(rnorm(100))
# create a new png file (e.g. plot-2.png) and the graphics is output to the file
abline(h = 0, col = "red")
# then the line is output to the file

The motivation of this is an attempt to avoid X11/Quartz forwarding (they do not play well with screen/tmux as the graphics are lost when user attaches the session from somewhere else), and to avoid xpra which there seems few people supporting it (causing Ubuntu 16.04 stuck at login screen, see https://askubuntu.com/questions/930161/ubuntu-16-04-2-cannot-login-after-installing-xpra?noredirect=1#comment1661998_930161).

It is quite like how RStudio Server handles R graphics (see source at https://github.com/rstudio/rstudio/tree/master/src/cpp/r/session/graphics). I'm wondering if there's an easier way to implement this (better not rewriting a graphic device from scratch)?

Upvotes: 2

Views: 1328

Answers (1)

r2evans
r2evans

Reputation: 160862

I'll quickly summarize how I use rmote, though the github page has much more information.

  1. ssh -L 4321:localhost:4321 remoteuser@remotehost
  2. tmux (or tmux attach if already started)
  3. emacs, start R using ESS
  4. Once, to get things started:

    library(rmote)
    start_rmote(server_dir="path/to/save/pngs")
    
  5. Make some plots, pointing your local web browser to http://127.0.0.1:4321. (Initially it'll show a directory listing, but once plots start it should auto-refresh.)

    plot(1:10, type='l')
    plot_done() # required for base-graphics
    plot(2:20)
    plot_done()
    library(ggplot2)
    ggplot(mtcars, aes(mpg, disp)) + geom_point() # no plot_done() required for ggplot2
    
  6. Disconnect from tmux/ssh. (The web page will likely fail since the tunnel is closed.)

  7. Reconnect, ssh -L 4321:localhost:4321 remoteuser@remotehost and tmux attach.
  8. Refresh the browser, all plots available (with full history still)
  9. When done, stop_rmote(). All plots are saved in path/to/save/pngs/plots/.

Bonus: if you do start_rmote(...) with the same directory, the same plot history will be available. So if you have to restart the R session, nothing has been lost. (I haven't tested it, but perhaps it'll work with simultaneous R sessions ...)

EDIT:

I often change the size of the plot, partly so I can fill the screen of my browser, but sometimes to set specific file sizes for reports or to replicate a different screen limitation.

options(rmote_device = list(type="png", retina=TRUE, width=1024, height=768))

Ref: https://github.com/cloudyr/rmote/blob/ee13936806cc1be5b2f95b70b33af374331ae2dc/man/rmote_device.Rd

EDIT 2: I guess I should note that, though perhaps under-utilizing the capabilities of rmote, it is certainly possible to use it just for the purposes of auto-PNG generation with most plotting methods. You don't have to connect to 127.0.0.1:4321 in order for the benefit of auto-saving PNGs to be realized.

Upvotes: 4

Related Questions