Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

A vital part of statistics is producing nice plots, an area where R is outstanding. The graphical ablility of R is often listed as a major reason for choosing the language. It is therefore funny that exporting these plots is such an issue in Windows. This post is all about how to export anti-aliased, high resolution plots from R in Windows.

There are two main problems when exporting graphics from R:

My previous solution to this problem has been to export my graph to a vector graphic (usually the SVG format), open it in Inkscape, and then export it to the resolution of choice. The vector graphics allows smooth scaling without me having to worry about the text becoming too small to read while at the same time adding the anti-aliasing. The down-side of this is that it is not really a convenient work-flow when you create knitr/Sweave documents where many plots are simultaneously generated.

## Exporting

Let us start by looking at an exported plot from RStudio, clearly not something I would like to send to a journal:

So the first alternative would be the standard library. We can kick-off with the svg() function as I mentioned it earlier (Note: If you can’t see the plot then your browser is probably old and does not support svg images):

?View Code RSPLUS
 1 2 3 4 5 6  svg(filename="Std_SVG.svg", width=5, height=4, pointsize=12) my_sc_plot(data) dev.off()

All images in this post use the same basic settings with minor tweaks:

• Width = 5 inches
• Height = 4 inches
• pointsize = 12

If we now do the same using the png() command we also have to set the resolution. I’m using 72 dpi (pixels/inch), as 1 point by the modern definition is 1/72 of the international inch and therefore a good start instead of the 96 dpi that Windows uses. As you can see the size of the labels are very similar to the svg():

?View Code RSPLUS
 1 2 3 4 5 6 7 8  png(filename="Std_PNG.png", units="in", width=5, height=4, pointsize=12, res=72) my_sc_plot(data) dev.off()

Note: The Cairo packages are obsolete as it usually is built in nowadays, all you need to do is remember to reference it – see my update

## The Cairo-package

The Cario package is an excellent choice for getting antia-aliased plots in Windows. Here’s the same plot from the Cairo package (the background is now transparent):

?View Code RSPLUS
 1 2 3 4 5 6 7 8 9 10  library(Cairo) Cairo(file="Cairo_PNG_72_dpi.png", type="png", units="in", width=5, height=4, pointsize=12, dpi=72) my_sc_plot(data) dev.off()

If we want to increase the resolution of the plot we can’t just change the resolution parameter:

?View Code RSPLUS
 1 2 3 4 5 6 7 8 9  Cairo(file="Cairo_PNG_96_dpi.png", type="png", units="in", width=5, height=4, pointsize=12, dpi=96) my_sc_plot(data) dev.off()

We also have to change the point size, the formula is size * new resolution DPI / 72 DPI:

?View Code RSPLUS
 1 2 3 4 5 6 7 8 9  Cairo(file="Cairo_PNG_96_dpi_adj.png", type="png", units="in", width=5, height=4, pointsize=12*92/72, dpi=96) my_sc_plot(data) dev.off()

If we double the image size we also need to double the point size:

?View Code RSPLUS
 1 2 3 4 5 6 7 8 9  Cairo(file="Cairo_PNG_72_dpi_x_2.png", type="png", units="in", width=5*2, height=4*2, pointsize=12*2, dpi=72) my_sc_plot(data) dev.off()

## The cairoDevice package

An alternative to the Cairo package is the cairoDevice package. It uses the same engine but has a slightly different syntax and due to it’s limitation in setting the resolution it really doesn’t work that well. Lets try the same as above:

?View Code RSPLUS
 1 2 3 4 5 6 7 8 9 10 11  # Detach the Cairo package just to make # sure that there aren't any conflicts detach("package:Cairo") library(cairoDevice) Cairo(filename="cairoDevice_SVG_pt12.svg", surface="png", width=5, height=4, pointsize=12) my_sc_plot(data) dev.off()

To be fair the default point size of the cairoDevice package, 8 points is less than for the Cairo package but even with that setting the image looks not that great:

After some tweaking I found that 5.2 points was fairly similar:

## Summary

The Cairo package does the job nicely and without too much hassle you can get the look exactly right. If you want the background to be white just add the bg parameter:

?View Code RSPLUS
 1 2 3 4 5 6 7 8 9 10  Cairo(file="Cairo_PNG_72_dpi_white.png", bg="white", type="png", units="in", width=5, height=4, pointsize=12, dpi=72) my_sc_plot(data) dev.off()

# Update

After Matt Neilsons excellent comment I’ve discovered that the standard export functions actually allow for anti-aliasing with built-in cairo support. Another excellent part is that the dpi now works exactly as expected – you don’t need to adjust the point size

?View Code RSPLUS
 1 2 3 4 5 6 7 8 9  png(filename="Std_PNG_cairo.png", type="cairo", units="in", width=5, height=4, pointsize=12, res=96) my_sc_plot(data) dev.off()

Here’s the plot code:

?View Code RSPLUS
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  # Create the data data <- rnorm(100, sd=15)+1:100 # Create a simple scatterplot # with long labels to enhance # size comparison my_sc_plot <- function(data){ par(cex.lab=1.5, cex.main=2) plot(data, main="A simple scatterplot", xlab="A random variable plotted", ylab="Some rnorm value", col="steelblue") x <- 1:100 abline(lm(data~x), lwd=2) }