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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With