Friday, January 13, 2012

Graphics (plots) in R for MacOS, Linux, and Windows

It seems that there is no universal, cross-operating-system way for opening and saving graphics in R, at least not with the functionality I'd like. 

[this post is updated/superseded by this one.]

Here's what I know so far --- but please let me know better ways and I'll update this post. I use Windows, so the info here about MacOS and Linux is what I've learned from readers, and I haven't tried it myself.

What I'd like to do: 1. Open a new graphics window. 2. Put plots into it. 3. Save it in any format of my choice. 4. Do this repeatedly, for a succession of graphs.

How to do it in Windows:
1. Use the windows()command to open a new graphics window.
2. Use plot(), lines(), etc. to make the graph.
3. Use the savePlot() command after the graph is drawn, with an appropriate argument to specify the desired format. File formats that work with savePlot() in Windows include "jpg", "pdf", "eps", etc. Note that savePlot() supersedes dev.copy2eps(), which was used in older versions of the programs.
4. Repeat as desired.

Equivalents for windows() in other operating systems:
  • Universal: dev.new(). The dev.new() function is great when running in the primitive editor that comes with R, but dev.new() fails in the RStudio editor, which does not allow repeated calls of dev.new(). Sigh. I don't know if repeated calls to dev.new() work in other editors or on other platforms. If you try and have information to share, please let me know.
  • MacOS: quartz(). You can change all the windows() calls to quartz(). The arguments in windows() default to windows(width,height), which might be different than quartz(). So, programs that use, say, windows(10,6) could be changed to quartz(width=10,height=6). But, I'm told that savePlot() does not work with a Mac window opened with quartz(). Sigh.
  • MacOS again: x11(). Mac users can also open a new window by using the x11() command, with which savePlot() does work. But I'm told that x11() can produce ugly fonts and strange proportions. Sigh. I'm told that x11( type="cairo", ... ) can do the trick.
  • Linux: x11(). But I haven't heard from anyone whether this really works without further modification. Linux users can try dev.new(), too, if they're not using RStudio.
Equivalents for savePlot() in other operating systems:
  • MacOS: If the window was opened with x11(), then savePlot() can work but you must specify a format type the MacOS knows about. For example, you cannot specify type="jpg" but must instead specify type="jpeg". If the window was opened with quartz(), then I am not aware of any way you can save the plot, after the fact, from the program command line. Perhaps you can use a pull-down menu item to manually save it.
  • Linux: I assume that savePlot(), with an appropriate type specification, will work. If there a Linux users out there who have tried it, please let me know.
An alternative procedure that works across platforms: Instead of creating the graph in a window and saving it after producing it, we open a "device" of the desired type before creating the graph, and then we close the device after the graph is done. For example, the pdf(file="fileName.pdf",...) command, in Windows, opens a device of type pdf. Then you draw the graph in the usual way. When done, close the device with the command dev.off() Thus:
pdf(file="fileName.pdf")
# plot commands go here
dev.off()
Besides pdf(), there are bmp(), jpeg(), png(), and tiff() commands for opening devices of different types. To see a complete list for your system, at the R command line type: help("Devices")

For providing these tips, I thank various readers, including George Kachergis, Reinhold Kliegl, Mark Perlin, Young Ahn, Uwe Ligges, and others.

7 comments:

  1. I use R on a Mac, and I have come to really like RStudio, which allows for pretty straightforward graphics control. It has a 'Plots' window, and it keeps your figures, even as you plot new ones. You can export keepers with a couple button clicks.

    I export figures from the 'Plots' window occasionally, but more often just use the RStudio figure panel for working on getting graphs to look the way I want, and then use, e.g., pdf() or png() (or whatever) and dev.off() as you describe.

    ReplyDelete
  2. Couldn't you start with dev.cur() using the current device, put all graphics instructions in the middle and close with dev.off()? That should work with Rstudio.

    ReplyDelete
  3. In Linux, x11() and savePlot() work like magic. Thanks for the helpful post.

    ReplyDelete
  4. To save a graphic from the Mac using quartz(), use the command quartz.save ("filename.pdf", "pdf") if you want to save the output as a PDF.

    ReplyDelete
  5. On Mac, you can also use dev.copy2pdf(file='fn.pdf') to copy the current quartz output

    ReplyDelete
  6. You can use dev.new() in RStudio. Just change the default device to be something else than the RStudio device like so:

    options( device = "quartz" );


    ReplyDelete
  7. Dear ecerulm:

    Thanks for your comment. It prompted me to edit this post with a link to a more recent one:

    http://doingbayesiandataanalysis.blogspot.com/2013/01/uniform-r-code-for-opening-saving.html

    Thanks again.

    ReplyDelete