Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop R from creating empty Rplots.pdf file when using ggsave and Rscript

Tags:

r

ggplot2

I have an R script that saves some plots using ggsave. When I run the script from the command line, it not only saves my plots but also an empty Rplots.pdf file. How can I prevent R from creating this unnecessary file?

Here is an example script that reproduces the error:

#!/usr/bin/env Rscript

# Code that creates unnecessary Rplots.pdf file
library(ggplot2)
my.data <- data.frame(x = 1:10, y = 1:10)
my.plot <- qplot(x, y, data = my.data)
ggsave('example.png', my.plot) 

All the following ways of running the script create the unnecessary file:

Rscript script.R
Rscript --vanilla script.R
chmod a+x script.R
./script.R 

Also, when I source the code from within an interactive session, an unnecessary blank R Graphics Device window opens.

Furthermore, I do not have these problems if I use the the following more verbose code in place of ggsave:

#!/usr/bin/env Rscript

# Code that does NOT create unnecessary Rplots.pdf file
library(ggplot2)
my.data <- data.frame(x = 1:10, y = 1:10)
my.plot <- qplot(x, y, data = my.data)
png(file = 'example.png')
print(my.plot)
dev.off()

Here is my session info (which is the same whether running Rscript or interactively):

R version 3.0.1 (2013-05-16)
Platform: x86_64-pc-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=C                 LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] methods   stats     graphics  grDevices utils     datasets  base     

other attached packages:
[1] ggplot2_0.9.3.1

loaded via a namespace (and not attached):
 [1] colorspace_1.2-2   dichromat_2.0-0    digest_0.6.3       grid_3.0.1        
 [5] gtable_0.1.2       labeling_0.1       MASS_7.3-26        munsell_0.4       
 [9] plyr_1.8           proto_0.3-10       RColorBrewer_1.0-5 reshape2_1.2.2    
[13] scales_0.2.3       stringr_0.6.2   

Update 5 years later (2018-08-02): This problem comes and goes. ggplot2 2.2.1 does not produce the empty file, ggplot2 3.0.0 does, and the ggplot2 team is currently working to fix this. For development history, see ggplot2 Issues #1326, #2363, #2758, and #2787.

like image 422
John Blischak Avatar asked Jun 27 '13 16:06

John Blischak


2 Answers

If you look at the defaults for the width and height arguments in ggsave, you'll see that they are par("din")[1] and par("din")[2]. If you run this in the console, you'll see that it opens a graphics window, if one isn't already open.

This sort of makes sense, since in order to get the device width/height in inches, you need an actual device. I suppose one could argue that par("din") should return an error if no device is open, in which case Hadley surely would have written ggsave differently.

Indeed, from ?par:

If the current device is the null device, par will open a new device before querying/setting parameters.

Hence, specifying a width/height will prevent the spurious device from opening.

like image 137
joran Avatar answered Nov 16 '22 00:11

joran


Another solution is to use the package R.devices to suppress the graphics device opened by ggsave:

library(R.devices)
suppressGraphics(ggsave('example.png', my.plot))

See the tweet from the package author for another example.

like image 31
John Blischak Avatar answered Nov 15 '22 22:11

John Blischak