25

I want to run R scripts and save the plots using png(). X11 is not supported on the Unix servers and I get the following error message:

Error in X11(paste("png::", filename, sep = ""), g$width, g$height, pointsize,  : 
  unable to start device PNG
Calls: png
In addition: Warning message:
In png("test.png", width = 900, height = 400) :
  unable to open connection to X11 display ''
Execution halted

Setting environment variables

Sys.setenv("DISPLAY"=":0.0")

or

Sys.setenv("DISPLAY"=":0")

in the R scripts didn't solve the problem.

This code example produces the error above:

library(ggplot2)
library(grid)

# Some data
df = data.frame(x = c(1.2,5,3,5.3,2,9,4,6,8,0), y = c(1.5,6,2.5,5.1,2.3,8.7,4.1,6,8,0))


# Base plot
p <- ggplot(df, aes(x,y)) + geom_point() +
   scale_x_continuous(limits = c(0, 8), expand = c(0,0)) +
   scale_y_continuous(limits = c(0, 8), expand = c(0,0)) +
   geom_smooth(method="lm", se=FALSE, formula=y~x, aes(colour="2"), show_guide=TRUE, fill=NA, size=1.2) +
   geom_vline(xintercept = 3) + geom_vline(xintercept = 7) +
   opts(plot.margin = unit(c(1,1,4,1), "lines"))

# Create the text Grobs
Text1 = textGrob("Part 1")
Text2 = textGrob("Part 2")
Text3 = textGrob("Part 3")

# Add the annotations
# Segment 1
p1 = p +
     annotation_custom(grob = linesGrob(), xmin = 0, xmax = 0, ymin = 
-1, ymax = -.75) +
     annotation_custom(grob = linesGrob(), xmin = 0, xmax = 3, ymin = 
-1, ymax = -1) +
     annotation_custom(grob = linesGrob(), xmin = 3, xmax = 3, ymin = 
-1, ymax = -.75) +
     annotation_custom(grob = Text1,  xmin = 0, xmax = 3, ymin = -1.25, 
ymax = -1.25)

# Segment 2
p1 = p1 +
     annotation_custom(grob = linesGrob(), xmin = 3, xmax = 7, ymin = 
-1, ymax = -1) +
     annotation_custom(grob = linesGrob(), xmin = 7, xmax = 7, ymin = 
-1, ymax = -.75) +
     annotation_custom(grob = Text2,   xmin = 3, xmax = 7, ymin = -1.25, 
ymax = -1.25)

# Segment 3
p1 = p1 +
     annotation_custom(grob = linesGrob(), xmin = 7, xmax = 8, ymin = 
-1, ymax = -1) +
     annotation_custom(grob = linesGrob(), xmin = 8, xmax = 8, ymin = 
-1, ymax = -.75) +
     annotation_custom(grob = Text3,  xmin = 7, xmax = 8, ymin = -1.25, 
ymax = -1.25)

png("test.png", width=900, height=400)

# Code to override clipping
gt <- ggplot_gtable(ggplot_build(p1))
gt$layout$clip[gt$layout$name=="panel"] <- "off"
grid.draw(gt)

dev.off()

The outcome of capabilities() is:

   jpeg      png     tiff    tcltk      X11     aqua http/ftp  sockets 
   FALSE    FALSE    FALSE     TRUE    FALSE    FALSE     TRUE     TRUE 

  libxml     fifo   cledit    iconv      NLS  profmem    cairo 
    TRUE     TRUE    FALSE     TRUE     TRUE    FALSE    FALSE

I am running the scripts via a sun grid engine.

Calimo
  • 7,510
  • 4
  • 39
  • 61
Matthias Munz
  • 3,583
  • 4
  • 30
  • 47
  • Was the R even compiled with X11 support? Check out `capabilities()` on the server. IIRC you can have an X virtual framebuffer instead of X which will allow this to work, but that assumes that the X virtual framebuffer package/software is installed on the server (on Linux, Fedora I can install xorg-x11-server-Xvfb for this purpose). If that fails, find a graphics device that is supported by your server, plot to that and retrieve the file and then convert to PNG on your local system – Gavin Simpson Oct 25 '12 at 11:54
  • 1
    How are you connected to the server? I think `ssh` has an option to turn on or off X11 tunneling. – Ari B. Friedman Oct 25 '12 at 11:56
  • jpeg png tiff tcltk X11 aqua http/ftp sockets FALSE FALSE FALSE TRUE FALSE FALSE TRUE TRUE libxml fifo cledit iconv NLS profmem cairo TRUE TRUE FALSE TRUE TRUE FALSE FALSE – Matthias Munz Oct 25 '12 at 13:19
  • What version of R are you on? If I unset DISPLAY and run R, I can do: png(file="foo.png");plot(1:10);dev.off() and get a PNG even though I can't talk to my X11 server (which I verify because X11() fails). I believe png uses cairo if there's no X11 if you have cairo in your capabilities. Which I don't think you do. Get it. – Spacedman Oct 25 '12 at 13:40

2 Answers2

40

if you are using R 3.0, try options(bitmapType='cairo') it worked for me

svural
  • 961
  • 1
  • 9
  • 17
3

I answered this once before -- can cannot make a program which expects X11 to certainly forget about it, but you can use the virtual framebuffer to 'pretend' X11 is present.

So see this older SO question for details and an example.

Community
  • 1
  • 1
Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725