I’ve cleaned up the code – please see the new version at:
https://github.com/sje30/essgd
Emacs can show images, such as PNG, SVG, PDF, in buffers. For a long time, I’ve wondered how to get output from R into an Emacs buffer. This is non-trivial as far as I know because you typically need to wrap your R code in calls to start an R device and then wait until the device is closed before the plot is created.
I recently saw this excellent video from Bruno Rodrigues introducing the httpgd package: https://www.youtube.com/watch?v=uxyhmhRVOfw. The httpgd package from Florian Rupprecht provides a web interface to his unified graphic device unigd. This allows you to view plots and tables in a web browser.
Although Emacs can view web content, e.g. with eww, the lack of javascript in Emacs means that the httpgd package doesn’t work directly. However, it can still be used to serve up SVG images of the plots which Emacs can then render. See the following movie for a proof of concept.
- Newish Emacs (tested on Emacs 29).
- ESS
- curl, perl, md5sum
- httpgd R package
- Clone this repo
chmod +x check_outputs.pl
- Open unigd.el and run
M-x eval-buffer
M-x R
within this directory (so it will findcheck_outputs.pl
).M-x ess-unigd-start
should then open up the placeholder filelatest.svg
.- Return to the R buffer and start plotting… In a background
buffer
*unigd-watcher*
you should see the output from the perl script as it polls httpgd.
Current approach is to use a perl script to check every 1 second to see if a new plot has been made. This approach might work well for running R remotely via TRAMP. A websocket implementation is now available in v2 folder.
Would a PNG rather than SVG be any more performant (to reduce flicker)?
The default image size sent by httpgd is 720x576. This could instead be determined by the current size of the Emacs buffer (and updated if the buffer changes size) using
(window-pixel-height) (window-pixel-width)
The httpgd server remembers the plots created so we should be able to dynamically go through the history of plots. See v2 for an implementation of this.