38

I'm trying to save a ggplot within a function using graphics devices. But I found the code produces empty graphs. Below is a very very simple example.

library(ggplot2)
ff <- function(){
  jpeg("a.jpg")
  qplot(1:20, 1:20)
  dev.off()
}
ff()

If I only run the content of the function, everything is fine. I know that using ggsave() will do the thing that I want, but I am just wondering why jpeg() plus dev.off() doesn't work. I tried this with different versions of R, and the problem persists.

rcs
  • 67,191
  • 22
  • 172
  • 153
Wei Wang
  • 381
  • 1
  • 3
  • 4
  • possible duplicate of [ggplot's qplot does not execute on sourcing](http://stackoverflow.com/questions/6675066/ggplots-qplot-does-not-execute-on-sourcing) – Ari B. Friedman Aug 12 '11 at 07:44
  • @gsk3 This question is in fact subtly different. Sufficient, in my view, to keep it open. The question you link to tries to display plots. This question wants to save a ggplot. So the correct answer in this case is to use `ggsave`, whereas the correct answer in the linked question is to use `print(p)` – Andrie Aug 12 '11 at 10:18
  • @Andrie: They say they know about ggsave, though; which makes the correct answer to "why jpeg() plus dev.off() doesn't work" the same as the linked question. You're right that it's subtly different and therefore probably worth keeping around though. – Ari B. Friedman Aug 12 '11 at 12:14
  • @gsk3 Thank you very much. I should have invested more before asking. – Wei Wang Aug 12 '11 at 14:29
  • 1
    So it _was_ a duplicate. – IRTFM Aug 12 '11 at 16:03

2 Answers2

47

You should use ggsave instead of the jpeg(); print(p); dev.off() sequence. ggsave is a wrapper that does exactly what you intend to do with your function, except that it offers more options and versatility. You can specify the type of output explicitly, e.g. jpg or pdf, or it will guess from your filename extension.

So your code might become something like:

p <- qplot(1:20, 1:20)
ggsave(filename="a.jpg", plot=p)

See ?ggsave for more details


The reason why the original behaviour in your code doesn't worked is indeed a frequently asked question (on stackoverlflow as well as the R FAQs on CRAN). You need to insert a print statement to print the plot. In the interactive console, the print is silently execututed in the background.

Community
  • 1
  • 1
Andrie
  • 176,377
  • 47
  • 447
  • 496
  • Thank you very much! It is indeed better to use `ggsave`. But I am modifying existing codes to replace default plotting system with ggplot, so I prefer sticking to `jpeg(); print(p); dev.off()` sequence. – Wei Wang Aug 12 '11 at 14:28
  • when i use ggsave within a loop the image loses colors and the legend – John Oct 13 '17 at 20:35
18

These plots have to be printed:

ff <- function(){
  jpeg("a.jpg")
  p <- qplot(1:20, 1:20)
  print(p)
  dev.off()
}
ff()

This is a very common mistake.

Community
  • 1
  • 1
joran
  • 169,992
  • 32
  • 429
  • 468