XKCD style graphs in R

What is XKCD?

As wikipedia states:

XKCD, is a webcomic created by Randall Munroe. The comic’s tagline describes it as a “Stick-figure strip featuring humour about technology, science, mathematics and relationships”

An example XKCD plot is below.

XKCD comic number 688. An example of what an XKCD comic looks like.

The XKCD package

In 2013 someone called Emilio Manzanera released a package caller xkcd onto CRAN. The package is basically a ggplot2 wrapper that makes graphs look like they came from an XKCD comic. It has three main functions: xkcdman, xkcdline and xkcdrect.

From the xkcd help file:

The xkcdman function creates a XKCD man and the other one plot pseudo handwritten objects. These functions are derived from the geom_path of the package ggplot2. All the funcionalities of the ggplot system can be used. See the vignettes for detailed examples.

Setting up

setwd("/Users/Jimmy/Dropbox/Personal/fun with code/xkcd")

library(xkcd)
library(extrafont)
library(ggplot2)

#Load scatter dataset
collegesdata <- read.csv("~/Dropbox/Personal/fun with code/xkcd/collegesdata.csv"
	)
	sapply(collegesdata, mode)
	head(collegesdata)

#Load bar dataset
bardata <- read.csv("~/Dropbox/Personal/fun with code/xkcd/bardata.csv"
	)
	sapply(bardata, mode)
	head(bardata)

#Load line graph
	linedata <- read.csv("~/Dropbox/Personal/fun with code/xkcd/p.csv"
	)
	sapply(linedata, mode)
	head(linedata)

#################################################
# Check font status

#do you have xkcd fonts?
if( "xkcd" %in% fonts()) {
  plo <- ggplot() + geom_point(aes(x=Year.founded, y=Fixed.assets), data=collegesdata) +
    theme(text = element_text(size = 16, family = "xkcd"))
} else {
  warning("xkcd fonts not installed! Read the text below")
}

#If warning,
#download the font and install it
#http://simonsoftware.se/other/xkcd.ttf
#On a mac, just click the link. Once downloaded click on the file
#then click install on the prompt. You're done.

# Load up fonts  

#then import all fonts - run line below on first run - it's SLOW
#font_import()

#load all fonts - run line below on first run
#loadfonts()

#opens the xkcd-intro.pdf
vignette("xkcd-intro")

Scatter plot

xrange <- range(collegesdata$Year.founded)
yrange <- range(collegesdata$Fixed.assets)
set.seed(1) # for reproducibility, as hand effect is just jitter

# R wouldn't let me use the xkcd font in a device - I didn't try and find away round
plot <- ggplot() + geom_point(aes(Year.founded, Fixed.assets), data=collegesdata) +
  xkcdaxis(xrange,yrange) +
  ylab("Fixed assets (pounds)")
  + xlab("Year founded") +
  labs(title="Cambridge college wealth \nagainst year founded")
plot
Scatter plot with an XKCD theme.

Bar plot

data <- bardata

#width of bars
data$xmin <- data$comroom - 0.1
data$xmax <- data$comroom + 0.1
data$ymin <- 0
data$ymax <- data$number

#Give some space to fit in text
xrange <- range(min(data$xmin)-0.3, max(data$xmax) + 0.5)
yrange <- range(min(data$ymin), max(data$ymax+50))
mapping <- aes(xmin=xmin,ymin=ymin,xmax=xmax,ymax=ymax)

plot2 <- ggplot() + xkcdrect(mapping,data) +
  xkcdaxis(xrange,yrange) +
  xlab("Jesus College Combination room") + ylab("Number of people") +
  annotate("text", x=1, y = 100, label = "Fellows", family="xkcd" ) +
  annotate("text", x=2, y = 220, label = "PhD'ers", family="xkcd" ) +
  annotate("text", x=3, y = 150, label = "Other grads", family="xkcd" ) +
  annotate("text", x=4, y = 490, label = "Undergrads", family="xkcd" )
plot2
An XKCD bar plot. Note the weird square boxes in the axis - these are because the font doesn't have the '(' symbol.

Line plot with stick figures

data <- linedata
yrange <- range(data$prev)
xrange <- range(data$year)
ratioxy <- 4
mapping <- aes(x,  y,
                  scale,
                  ratioxy,
                  angleofspine ,
                  anglerighthumerus,
                  anglelefthumerus,
                  anglerightradius,
                  angleleftradius,
                  anglerightleg,
                  angleleftleg,
                  angleofneck)
dataman <- data.frame( x= c(2003,2020), y=c(11, 4.5),
                         scale = 0.6,
                         ratioxy = ratioxy,
                         angleofspine =  -pi/2  ,
                         anglerighthumerus = c(-pi/6, -pi/6),
                         anglelefthumerus = c(-pi/2 - pi/6, -pi/2 - pi/6),
                         anglerightradius = c(pi/5, -pi/5),
                         angleleftradius = c(pi/5, -pi/5),
                         angleleftleg = 3*pi/2  + pi / 12 ,
                         anglerightleg = 3*pi/2  - pi / 12,
                         angleofneck = runif(1, 3*pi/2-pi/10, 3*pi/2+pi/10))
datalines <- data.frame(xbegin=c(2005,2021.6),ybegin=c(11,4.5),
	xend=c(2006,2022.1), yend=c(11.2,4.7))
p <- ggplot() + geom_smooth(mapping=aes(x=year, y =prev, colour=as.character(country)),
                            ,se=FALSE, data =data, method="loess")
p + xkcdaxis(xrange,yrange) +
    ylab("Predicted raw prevelance of diabetes (percent)") +
    xkcdman(mapping, dataman) +
    scale_colour_discrete(name = "Country")+
    annotate("text", x=2010.5, y = 11.7, label = "Diabetes is\nincreasing!",
    	family="xkcd" ) +
    annotate("text", x=2024.5,
    	y = 5.6,
    	label = "Left of the dotted line \nare collected data\nright side are IDF predictions",
    	family="xkcd" ) +
    xkcdline(aes(xbegin=xbegin,ybegin=ybegin,xend=xend,yend=yend),
    	datalines, xjitteramount = 0.12) +
    geom_vline(xintercept=c(2013), linetype="dotted")
Line plot, with two individuals drawn using the xkcdman function.
A post about: , and

You May Also Enjoy