XKCD-Style Plots in R

The new version of ggplot2 introduces themes, which make it easy to stylize your graphs. Naturally, people have been hard at work duplicating the XKCD hand-drawn style. I cribbed together some code from various folks answering on the Stack Overflow question, and the results are fairly convincing. Here are the weekly pageviews for my website:

And here’s the code. Note the need for the brand new extrafonts package if you want to use the XKCD style font, which is downloaded from the web:

library(ggplot2)
library(extrafont)

# Download XKCD-style font
download.file("http://simonsoftware.se/other/xkcd.ttf", dest="xkcd.ttf")

# Import the font and load fonts
font_import(".")
loadfonts()

# Load data, exported from Google Analytics
site_data = read.csv("/path/to/Analytics_20120101-20121110.csv")

# Make plot with ggplot
p <- ggplot(site_data, aes(x=Week, y=Pageviews)) + 
    geom_point() +
    geom_smooth(position="jitter", fill=NA, method="loess", size=2) +
    ggtitle("Pageviews: Jan. 2012 to Nov. 2012") +
    xlab("Week") + ylab("Number of Views") +
    theme(text=element_text(size=16, family="xkcd"))

# Show plot
p

Quick Precipitation Plots in R

Kay Cichini over at theBioBucket has a post about plotting climate data from KNMI Climate Explorer. It was a cool little script, so I stole it, switched a few things around, and ran it on a few locales. (You can find the station ID with this search page.) Here’s the annual rainfall for NYC, Antananarivo (the capital of Madagascar), and Swakopmund (a little city on the edge of the Namib Desert), with the modified script below. It could be useful for science folk giving presentations and needing a quick graph.

nyc_dat <- read.table ("http://climexp.knmi.nl/data/pa72503.1.dat",
    sep="",
    row.names=1,
    col.names=0:12)
	
# Turn -999.9 to NA, so R can understand it
nyc_dat[nyc_dat == -999.9] = NA

dev.new(width = 15, height = 5)

plot(rowSums(nyc_dat), 
    type = "s", 
    ylab = "Annual Total Precipitation (mm)", 
    xlab = NA, col = "blue", xaxt = "n", 
    lwd = 1.5, las = 2, cex.axis = 0.8,
    main = "NEW YORK CENTRAL PARK, 40.79N, -73.97E...") 

# Only print axis lables every 5 years

min_year = as.numeric(min(row.names(nyc_dat)))
max_year = as.numeric(max(row.names(nyc_dat)))

# Estimates number of axis labels to add
num_ticks = (max_year - min_year) / 5

axis_to_print = pretty(min_year:max_year, n=num_ticks) - min_year + 1

# Get rid of negative indices
axis_to_print = axis_to_print[-axis_to_print < 0]
# And of indices that are outside the range of our data
axis_to_print = axis_to_print[axis_to_print <= nrow(nyc_dat)]

axis(1, labels = rownames(nyc_dat)[axis_to_print], at = axis_to_print, 
    las = 2, cex.axis = 0.85)

# Add line for average
abline(h = mean(rowSums(nyc_dat), na.rm=TRUE), col = 1, lty = 2, lwd = 1.2)

# Add label and arrow
text(x = -2.5, 
     y = 0.9*max(rowSums(nyc_dat), na.rm=TRUE),
     adj = 0, 
     paste("Long-term average = ", 
           round(mean(rowSums(nyc_dat), na.rm=TRUE)), 
           " mm"),
     cex = 0.75)
		
arrows(x0 = -0.5, y0 = 0.875*max(rowSums(nyc_dat), na.rm=TRUE),
       x1 = -0.5, y1 = mean(rowSums(nyc_dat), na.rm=TRUE) + 50, length = 0.05)