Search code examples
rlinuxx11jupyter-notebookjupyter-irkernel

How to run jupyter Rkernel notebook with inline graphics on machine without display?


I often run jupyter IPython notebooks on a linux cluster compute node without X11 with no problems. However, running the R kernel on the same setup is not working very well.

The machine details are:

  • CentOS 7.2
  • R 3.3.1 with X11, png, and cairo capabilities
  • Anaconda 4.0.0 (python 2.7.11)

Just starting the notebook causes the kernel to crash after the first cell is run with this in the log:

unable to open connection to X11 display ''

I can get it to work by starting the notebook with xvfb-run jupyter notebook. This lets me run R commands in the cells but when I try to produce plots, I get the following

Error in grid.Call(L_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : X11  font -adobe-helvetica-%s-%s-*-*-%d-*-*-*-*-*-*-*, face 1 at size 9 could not be loaded

I suppose that if I could install the x11 fonts it would work, but this is on a compute node of a cluster and I don't have the administrative privileges to install them.

What is the correct way to configure jupyter notebook with the R kernel to produce graphics on a linux machine without X11?


Solution

  • I think that I've found the minimal configuration necessary for the irkernel when running the notebook on a linux machine with no display hardware and no physical input devices.

    Run the notebook under the virtual framebuffer X server, xvfb:

    xvfb-run jupyter notebook
    

    Use cairo instead of X11:

    # Run this in a notebook cell, or put in .Rprofile
    options(bitmapType="cairo")
    

    Set the jupyter.plot_mimetype. SVG looks much better and worked fine for me. PNG was ok too:

    # Run this in a notebook cell, or put in .Rprofile
    # svg much clearer, but won't rescale (scrolling works though)
    options(jupyter.plot_mimetypes = "image/svg+xml")
    # png had some artifacts, but had the nice feature that it would
    # resize when the browser window changes size
    #options(jupyter.plot_mimetypes = 'image/png')
    # can easily resize plots (have to re-plot) with this:
    #options(repr.plot.width=14, repr.plot.height=4)