Skip to content
Home ยป How to anti-alias plots in R

How to anti-alias plots in R

In this blog post I elaborate on anti-aliasing in R. Some feedback I received quite a while is that the plots produced by ggplot2 in R aren’t as pretty as those produced by Microsoft Office, or even Python’s Matplotlib. This feedback is justified, because R doesn’t anti-alias it’s produced plots. So I searched and somewhere in Egypt I found a solution.

What is anti-aliasing? Wikipedia defines it as: “a technique for minimizing the distortion artifacts known as aliasing when representing a high-resolution image at a lower resolution.” In other words, in the real world, a diagonal line looks nice. But your computer uses a monitor with a two-dimensional grid with pixels. To draw that diagonal line, you can’t colorize half a pixel. Enter: anti-alising.

There are many ways to anti-alias an object, but the image below represents a common one. The pixels close to your diagonal line are colorized in a color that’s somewhere in between the line and the other pixels nearby. A black line on a white background produces some extra pixels in a shade of grey.

That’s why your plots produced by R look ugly: the objects within it aren’t anti-aliased. At least… in Windows. Because anti-alising already works out of the box in R on MacOS. If you have you produced visualizations in R on a MacOS device, you might have noticed that they look much smoother.

The solution in Windows is to switch to another rendering engine that does provide anti-alising. A good option is Cairo. It’s open source. It’s device-independent, which means it will produce the same result on every device. And you can install the Cairo library easily and load it as follows:

install.packages('Cairo')
library('Cairo')
CairoWin()

The CairoWin() function initializes a new graphics device that uses the cairo graphics library for rendering. If you use ggplot now, your plots will be rendered in a new window that uses the cairo library. Here is an example:

data('nhtemp')
dt <- data.table(nhtemp)
dt[,year := ymd(paste0(seq(1912,1971,1),'-01-01'))]

g <- ggplot(dt,aes(x = year, y = nhtemp, group = 1)) + 
  geom_line(size = 1) + 
  geom_point(size = 3)

You can save your images by providing the parameter type=’cairo’ to the ggsave() function.

ggsave(g, filename = 'nhtemp_with_cairo.png', dpi = 300, type = 'cairo',
       width = 8, height = 4, units = 'in')

Here’s the difference. This one is with anti-alaising:

And this one is without anti-alaising:

The difference? Take a look at this:

By the way, if you’re having trouble understanding some of the code and concepts, I can highly recommend “An Introduction to Statistical Learning: with Applications in R”, which is the must-have data science bible. If you simply need an introduction into R, and less into the Data Science part, I can absolutely recommend this book by Richard Cotton. Hope it helps!

Say thanks, ask questions or give feedback

Technologies get updated, syntax changes and honestly… I make mistakes too. If something is incorrect, incomplete or doesn’t work, let me know in the comments below and help thousands of visitors.

5 thoughts on “How to anti-alias plots in R”

  1. Hello, so I found this post by accident. If you use R studio, the newer versions should have an option to swith to the cairo graphics device by default. It’s under options, general, graphics.
    The problem is when you use R outside of R studio, it tends to pick the default windows driver. :/
    I wonder if there is a way how to force R to use the cairo engine, without the need to generate a .png somewhere. It’s probably some kind of dev option somewhere.

  2. Many thanks for this. I was using Cairo 5 years back just for this, then I kind of dropped it because plotly::ggplotly() does it by default… now I need png files for web use without JS… googled this post and am so delighted. I worked in geophysics/signal processing and anti-alias was a *must* obviously in field recordings but some folks don’t ‘get it’ with spatial aliasing.

Leave a Reply

Your email address will not be published. Required fields are marked *