The trend is slowly moving towards interactive plotting and reproducible research with e.g. knitR (which I fully support), but it seems to me that R/ggplot2 is still the best plotting system for static graphics. That said, ggplot’s stock settings leave a lot to be desired, and I usually find myself having to do a lot of tweaking before a plot is ready to be put on paper. Recently, I got around to actually incorporating most of my usual settings into a theme, which I’m making available in case anyone finds it useful.
Let’s take a look at ggplot’s default settings for a few different plots:
A few things to note:
- The text is too small.
- A plot should draw the eye to the data, but the dark grey background is so noisy that the data doesn’t pop out the way it should.
- The grid lines are likewise too noticeable. They draw the eye away from the data.
- The color is obviously unsuitable for most publications.
The built in
theme_bw()
solves several of these problems, but not all of them, so I’ve put together a simple, minimalist black and white theme that produces plots which are more or less publication ready “out of the box”, save for data specific tweaking. There’s really not much too it — we just do away with most of the unnecessary shading and set the text size to something more legible. Unfortunately, plot color is not “theme-able”, so the greyscale has to be set up manually, but that’s easy. This is what it looks like:
The source code:
theme_pub <- function (base_size = 12, base_family = "") { theme_grey(base_size = base_size, base_family = base_family) %+replace% theme(# Set text size plot.title = element_text(size = 18), axis.title.x = element_text(size = 16), axis.title.y = element_text(size = 16, angle = 90), axis.text.x = element_text(size = 14), axis.text.y = element_text(size = 14), strip.text.x = element_text(size = 15), strip.text.y = element_text(size = 15, angle = -90), # Legend text legend.title = element_text(size = 15), legend.text = element_text(size = 15), # Configure lines and axes axis.ticks.x = element_line(colour = "black"), axis.ticks.y = element_line(colour = "black"), # Plot background panel.background = element_rect(fill = "white"), panel.grid.major = element_line(colour = "grey83", size = 0.2), panel.grid.minor = element_line(colour = "grey88", size = 0.5), # Facet labels legend.key = element_rect(colour = "grey80"), strip.background = element_rect(fill = "grey80", colour = "grey50", size = 0.2)) }
With this defined, it's enough to append
theme_pub()
to your plot object. For example, a simple histogram in ggplot2 might be made with
data = data.frame(x = rnorm(100)) p = ggplot(data, aes(x = x)) + geom_histogram()
to apply the theme, simply define the theme function and write
data = data.frame(x = rnorm(100)) p = ggplot(data, aes(x = x)) + geom_histogram() + theme_pub()
Unfortunately, ggplot will still, by default, label different conditions by color, rather than with different shades of grey. To fix this, use one of
scale_fill_grey(start = 0, end = .9) scale_color_grey(start = 0, end = .9)
depending on your plot.