# Animint Tutorial

This tutorial is designed to demonstrate animint, a package that converts ggplot2 plots into d3 javascript graphics. Animint allows you to make interactive web-based graphics using familiar R methods. In addition, animint allows graphics to be animated and respond to user clicks.

## Contents

• Introduction
• Tornado Example - see what animint can do, including explanations of clickSelects, showSelected, and animations.
• Climate Example - another demonstration of using animint with multiple linked plots and animation.
• Examples of Geoms - explanations of how to use statistics and certain geoms in animint, demonstrations of most geoms that animint supports.
• Lines
• Points
• Interactive Points - short introduction to clickSelects and showSelected with familiar geoms.
• Other Geoms - abline, area, bar, contour, density,…
This section also includes discussions of problem statistics and some unimplemented geoms and how to get around them.

## Lines

### Simple lines

This should work exactly as in ggplot2.

``````#' Generate data
data <- data.frame(x=rep(1:10, times=5), group = rep(1:5, each=10))
data\$lt <- c("even", "odd")[(data\$group%%2+1)] # linetype
data\$group <- as.factor(data\$group)
data\$y <- rnorm(length(data\$x), data\$x, .5) + rep(rnorm(5, 0, 2), each=10)

#' Simple line plot
p1 <- ggplot() + geom_line(data=data, aes(x=x, y=y, group=group)) +
ggtitle("geom_line")
p1
``````

``````

#' Simple line plot with colours...
p2 <- ggplot() + geom_line(data=data, aes(x=x, y=y, colour=group, group=group)) +
ggtitle("geom_line + scale_colour_discrete")
p2
``````

``````
gg2animint(list(p1=p1, p2=p2), out.dir="geoms/linessimple")
``````

### Linetypes

ggplot2 has several methods of linetype specification, all of which are supported in animint.

``````#' Simple line plot with colours and linetype
p3 <- ggplot() + geom_line(data=data, aes(x=x, y=y, colour=group, group=group, linetype=lt)) +
ggtitle("geom_line + scale_linetype_manual")
p3
``````

``````
#' Use automatic linetypes from ggplot with coerced factors
p4 <- ggplot() + geom_line(data=data, aes(x=x, y=y, colour=group, group=group, linetype=group)) +
ggtitle("geom_line + scale_linetype automatic")
p4
``````

``````
#' Manually specify linetypes using <length, space, length, space...> notation
data\$lt <- rep(c("2423", "2415", "331323", "F2F4", "solid"), each=10)
p5 <- ggplot() + geom_line(data=data, aes(x=x, y=y, colour=group, group=group, linetype=lt)) +
scale_linetype_identity("group", guide="legend", labels = c("1", "2", "3", "4", "5")) +
scale_colour_discrete("group") +
ggtitle("Manual Linetypes: dash-space length")
p5
``````

``````
#' All possible linetypes
lts <- scales::linetype_pal()(13)
lt1 <- data.frame(x=0, xend=.25, y=1:13, yend=1:13, lt=lts, lx = -.125)
p6 <- ggplot()+geom_segment(data=lt1, aes(x=x, xend=xend, y=y, yend=yend, linetype=lt)) +
scale_linetype_identity() + geom_text(data=lt1, aes(x=lx, y=y, label=lt), hjust=0) +
ggtitle("Scales package: all linetypes")

lts2 <- c("solid", "dashed", "dotted", "dotdash", "longdash", "twodash")
lt2 <- data.frame(x=0, xend=.25, y=1:6, yend=1:6, lt=lts2, lx=-.125)
p7 <- ggplot() + geom_segment(data=lt2, aes(x=x, xend=xend, y=y, yend=yend, linetype=lt)) +
scale_linetype_identity() + geom_text(data=lt2, aes(x=lx, y=y, label=lt), hjust=0) +
ggtitle("Named linetypes")

gg2animint(list(p3=p3, p4=p4, p5=p5, p6=p6, p7=p7), out.dir="geoms/linetypes")
``````

Animint Plot

### Alpha scales and lines

``````#' Spaghetti Plot Data
n <- 500
pts <- 10
data2 <- data.frame(x=rep(1:pts, times=n), group = rep(1:n, each=pts))
data2\$group <- as.factor(data2\$group)
data2\$y <- rnorm(length(data2\$x), data2\$x*rep(rnorm(n, 1, .25), each=pts), .25) + rep(rnorm(n, 0, 1), each=pts)
data2\$lty <- "solid"
data2\$lty[which(data2\$group%in%subset(data2, x==10)\$group[order(subset(data2, x==10)\$y)][1:floor(n/10)])] <- "3133"
data2 <- ddply(data2, .(group), transform, maxy = max(y), miny=min(y))
data2\$below0 <- factor(sign(data2\$miny)<0)

qplot(data=data2, x=x, y=y, group=group, geom="line", alpha=I(.2))
``````

``````
#' scale_alpha
p8 <- ggplot() + geom_line(data=data2, aes(x=x, y=y, group=group), alpha=.1) +
ggtitle("Constant alpha")
p8
``````

``````
p9 <- ggplot() + geom_line(data=subset(data2, as.numeric(group) < 50),
aes(x=x, y=y, group=group, linetype=lty), alpha=.2) +
scale_linetype_identity() +
ggtitle("Constant alpha, I(linetype)")
p9
``````

``````
p10 <- ggplot() + geom_line(data=subset(data2, as.numeric(group) < 50),
aes(x=x, y=y, group=group, linetype=below0, alpha=maxy)) +
scale_alpha_continuous(range=c(.1, .5)) +
ggtitle("Continuous alpha")
p10
``````

``````
#' Size Scaling
p11 <- ggplot() + geom_line(data=subset(data2, as.numeric(group)%%50 ==1),
aes(x=x, y=y, group=group, size=(floor(miny)+3)/3)) +
scale_size_continuous("Line Size", range=c(1,3)) +
ggtitle("Continuous size")
p11
``````

``````
p12 <- ggplot() + geom_line(data=data2, aes(x=x, y=y, group=group, alpha=miny, colour=maxy)) +
scale_alpha_continuous(range=c(.1, .3)) +
ggtitle("Continuous Alpha and Colour")
p12
``````

``````gg2animint(list(p8=p8, p9=p9, p10=p10, p11=p11, p12=p12), out.dir="geoms/alphalines")
``````

Animint plot

## Points

In general, points are exactly the same in animint and ggplot2, with two exceptions:

• Shapes are not supported in animint at this time, because d3 only provides about 6 shapes total, and it is thus not possible to map shapes from R to d3 faithfully.
• In R, most shapes do not have separate colour and fill attributes. In d3, points have both colour and fill attributes, so it is possible to get at least 2 shapes with animint: filled and open circles.
• If you specify colour but not fill, animint will attempt to set fill for you. If you want open circles, use fill=NA.
• Specifying colour and fill will work in animint, but may not show up on the ggplot2 plot, as ggplot2 does not typically use the fill aesthetic for points. ### scale_colour and geom_point
``````# Randomly generate some data
scatterdata <- data.frame(x=rnorm(100, 50, 15))
scatterdata\$y <- with(scatterdata, runif(100, x-5, x+5))
scatterdata\$xnew <- round(scatterdata\$x/20)*20
scatterdata\$xnew <- as.factor(scatterdata\$xnew)
scatterdata\$class <- factor(round(scatterdata\$x/10)%%2, labels=c("high", "low"))
scatterdata\$class4 <- factor(rowSums(sapply(quantile(scatterdata\$x)+c(0,0,0,0,.1), function(i) scatterdata\$x<i)), levels=1:4, labels=c("high", "medhigh", "medlow", "low"), ordered=TRUE)

s1 <- ggplot() + geom_point(data=scatterdata, aes(x=x, y=y)) +
xlab("very long x axis label") +
ylab("very long y axis label") +
ggtitle("Titles are awesome")
s1
``````

``````
#' Colours, Demonstrates axis -- works with factor data
#' Specify colours using R colour names
s2 <- ggplot() + geom_point(data=scatterdata, aes(x=xnew, y=y), colour="blue") +
ggtitle("Colours are cool")
s2
``````

``````
#' Specify colours manually using hex values
s3 <- ggplot() +
geom_point(data=scatterdata, aes(x=xnew, y=y, colour=class, fill=class)) +
scale_colour_manual(values=c("#FF0000", "#0000FF")) +
scale_fill_manual(values=c("#FF0000", "#0000FF")) +
ggtitle("Manual colour/fill scales")
s3
``````

``````
#' Categorical colour scales
s4 <- ggplot() + geom_point(data=scatterdata, aes(x=xnew, y=y, colour=xnew, fill=xnew)) +
ggtitle("Categorical colour/fill scales")
s4
``````

``````
#' Color by x*y axis (no binning)
s6 <- ggplot() + geom_point(data=scatterdata, aes(x=x, y=y, color=x*y, fill=x*y)) +
ggtitle("Continuous color scales")
s6
``````

``````
gg2animint(list(s1=s1, s2=s2, s3=s3, s4=s4, s6=s6), out.dir="geoms/simplepoints")
``````

### geom_jitter

``````s5 <- ggplot() + geom_jitter(data=scatterdata, aes(x=xnew, y=y, colour=class4, fill=class4)) +
ggtitle("geom_jitter")
s5
``````

``````gg2animint(list(s5=s5), out.dir="geoms/jitterpoints")
``````

Animint plot

### Interactive plots and scale_size

With showSelected, it is sometimes useful to have two copies of a geom - one copy with low alpha that has no showSelected or clickSelects attributes, and another copy that is interactive. This allows the data to be visible all the time while still utilizing the interactivity of d3.

``````library(plyr)
scatterdata2 <- data.frame(x=rnorm(1000, 0, .5), y=rnorm(1000, 0, .5))
scatterdata2\$quad <- c(3, 4, 2, 1)[with(scatterdata2, (3+sign(x)+2*sign(y))/2+1)]
scatterdata2 <- ddply(scatterdata2, .(quad), transform, str=sqrt(x^2+y^2)/4)
scatterdata2.summary <- ddply(scatterdata2, .(quad), summarise, xmin=min(x), xmax=max(x), ymin=min(y), ymax=max(y), xmean=mean(x), ymean=mean(y))
``````

``````
#' Interactive plots...
s7 <- ggplot() +
geom_rect(data=scatterdata2.summary, aes(xmax=xmax, xmin=xmin, ymax=ymax, ymin=ymin,
geom_point(data=scatterdata2, aes(x=x, y=y), alpha=.15) +
scale_colour_discrete(guide="legend") + scale_fill_discrete(guide="legend") +
scale_alpha_discrete(guide="none") +
ggtitle("Selects & Means")
s7
``````

``````
#' Single alpha value
s8 <- ggplot() +
guides(colour = guide_legend(override.aes = list(alpha = 1)),
fill = guide_legend(override.aes = list(alpha = 1))) +
ggtitle("Constant alpha")
s8
``````
``````## Warning: Duplicated override.aes is ignored.
``````

``````
#' Continuous alpha
s9 <- ggplot() +
guides(colour = guide_legend(override.aes = list(alpha = 1)),
fill = guide_legend(override.aes = list(alpha = 1))) +
scale_alpha(range=c(.6, 1), guide="none") +
ggtitle("Continuous alpha")
s9
``````
``````## Warning: Duplicated override.aes is ignored.
``````

``````
#' Categorical alpha and scale_alpha_discrete()
#' Note, to get unselected points to show up, need to have two copies of geom_point: One for anything that isn't selected, one for only the selected points.
s10 <- ggplot() +
guides(colour = guide_legend(override.aes = list(alpha = 1)),
fill = guide_legend(override.aes = list(alpha = 1))) +
scale_alpha_discrete(guide="none")+
ggtitle("Discrete alpha")
s10
``````
``````## Warning: Duplicated override.aes is ignored.
``````

``````

#' Point Size Scaling
#' Scale defaults to radius, but area is more easily interpreted by the brain (Tufte).
s11 <- ggplot() +
ggtitle("Scale Size")
s11
``````

``````

s12 <- ggplot() +
scale_size_area() +
ggtitle("Scale Area")
s12
``````

``````
gg2animint(list(s7=s7, s8=s8, s9=s9, s10=s10, s11=s11, s12=s12), out.dir="geoms/interactivepoints")
``````
``````## Warning: Duplicated override.aes is ignored. Warning: Duplicated
## override.aes is ignored. Warning: Duplicated override.aes is ignored.
``````

## Other geoms

``````library(ggplot2)
library(plyr)
library(animint)
``````

### geom_abline

``````xydata <- data.frame(x=sort(runif(50, 0, 10)))
xydata\$y <- 3+2*xydata\$x + rnorm(50, 0, 1)
g1 <- ggplot() + geom_point(data=xydata, aes(x=x, y=y)) +
geom_abline(data=data.frame(intercept=c(3, 0), slope=c(2,1)), aes(intercept=intercept, slope=slope)) +
ggtitle("geom_abline")
g1
``````

``````gg2animint(list(g1=g1), out.dir="geoms/abline")
``````

### geom_ribbon

``````ribbondata <- data.frame(x=seq(0, 1, .1), ymin=runif(11, 0, 1), ymax=runif(11, 1, 2))
ribbondata <- rbind(cbind(ribbondata, group="low"), cbind(ribbondata, group="high"))
ribbondata[12:22,2:3] <- ribbondata[12:22,2:3]+1
g2 <- ggplot() +
geom_ribbon(data=ribbondata, aes(x=x, ymin=ymin, ymax=ymax, group=group, fill=group), alpha=.5) +
ggtitle("geom_ribbon")
g2
``````

``````gg2animint(list(g2=g2), out.dir="geoms/ribbon")
``````

Animint plot

### geom_tile

``````tiledata <- data.frame(x=rnorm(1000, 0, 3))
tiledata\$y <- rnorm(1000, tiledata\$x, 3)
tiledata\$rx <- round(tiledata\$x)
tiledata\$ry <- round(tiledata\$y)
tiledata <- ddply(tiledata, .(rx,ry), summarise, n=length(rx))

g3 <- ggplot() + geom_tile(data=tiledata, aes(x=rx, y=ry, fill=n)) +
xlab("x") + ylab("y") + ggtitle("geom_tile")
g3
``````

``````gg2animint(list(g3=g3), out.dir="geoms/tile")
``````

Animint plot

### geom_path

``````pathdata <- data.frame(x=rnorm(30, 0, .5), y=rnorm(30, 0, .5), z=1:30)
g4 <- ggplot() + geom_path(data=pathdata, aes(x=x, y=y), alpha=.5) +
geom_text(data=pathdata, aes(x=x, y=y, label=z)) +
ggtitle("geom_path")
g4
``````

``````gg2animint(list(g4=g4), out.dir="geoms/path")
``````

Animint plot

### geom_polygon

``````polydata <- rbind(
data.frame(x=c(0, .5, 1, .5, 0), y=c(0, 0, 1, 1, 0), group="parallelogram", fill="blue", xc=.5, yc=.5),
data.frame(x=c(.5, .75, 1, .5), y=c(.5, 0, .5, .5), group="triangle", fill="red", xc=.75, yc=.33)
)
g5 <- ggplot() +
geom_polygon(data=polydata, aes(x=x, y=y, group=group, fill=fill, colour=fill), alpha=.5)+
scale_colour_identity() + scale_fill_identity()+
geom_text(data=polydata, aes(x=xc, y=yc, label=group)) +
ggtitle("geom_polygon")
g5
``````

``````gg2animint(list(g5=g5), out.dir="geoms/polygon")
``````

Animint plot

### geom_linerange

``````boxplotdata <- rbind(data.frame(x=1:50, y=sort(rnorm(50, 3, 1)), group="N(3,1)"),
data.frame(x=1:50, y=sort(rnorm(50, 0, 1)), group="N(0,1)"),
data.frame(x=1:50, y=sort(rgamma(50, 2, 1/3)), group="Gamma(2,1/3)"))
boxplotdata <- ddply(boxplotdata, .(group), transform, ymax=max(y), ymin=min(y), med=median(y))

g6 <- ggplot() +
geom_linerange(data=boxplotdata, aes(x=factor(group), ymax=ymax, ymin=ymin, colour=factor(group))) +
ggtitle("geom_linerange") + scale_colour_discrete("Distribution") + xlab("Distribution")
g6
``````

``````gg2animint(list(g6=g6), out.dir="geoms/linerange")
``````

Animint plot

### geom_histogram

``````g7 <- ggplot() +
geom_histogram(data=subset(boxplotdata, group=="Gamma(2,1/3)"), aes(x=y, fill=..count..), binwidth=1) +
ggtitle("geom_histogram")
g7
``````

``````gg2animint(list(g7=g7), out.dir="geoms/histogram")
``````

Animint plot

### geom_violin

``````g8 <- ggplot() +
geom_violin(data=boxplotdata, aes(x=group, y=y, fill=group, group=group)) +
ggtitle("geom_violin")+ scale_fill_discrete("Distribution") + xlab("Distribution")
g8
``````

``````gg2animint(list(g8=g8), out.dir="geoms/violin")
``````

Animint plot

### geom_step

``````g9 <- ggplot() + geom_step(data=boxplotdata, aes(x=x, y=y, colour=factor(group), group=group)) +
scale_colour_discrete("Distribution") +
ggtitle("geom_step")
g9
``````

``````gg2animint(list(g9=g9), out.dir="geoms/step")
``````

Animint plot

### geom_contour

``````library(reshape2) # for melt
contourdata <- melt(volcano)
names(contourdata) <- c("x", "y", "z")
g11 <- ggplot() + geom_contour(data=contourdata, aes(x=x, y=y, z=z), binwidth=4, size=0.5) +
geom_contour(data=contourdata, aes(x=x, y=y, z=z), binwidth=10, size=1) +
ggtitle("geom_contour")
g11
``````

``````
gg2animint(list(g11=g11), out.dir="geoms/contour")
``````

Animint plot

``````contourdata2 <- floor(contourdata/3)*3 # to make fewer tiles

g12 <- ggplot() +
geom_tile(data=contourdata2, aes(x=x, y=y, fill=z, colour=z)) +
geom_contour(data=contourdata, aes(x=x, y=y, z=z), colour="black", size=.5) +
scale_fill_continuous("height", low="#56B1F7", high="#132B43", guide="legend") +
scale_colour_continuous("height", low="#56B1F7", high="#132B43", guide="legend") +
ggtitle("geom_tile + geom_contour")
g12
``````

``````
gg2animint(list(g12=g12), out.dir="geoms/contour2")
``````

Animint plot. You may have to wait a moment to see the tiles - as each tile is a separate d3 object, it can take a few seconds to load all of the tiles.

### scale_y_log10 and geom_contour with stat_density2d

While stat_density2d does not always work reliably, we can still use the statistic within another geom, such as geom_contour.

``````library("MASS")
data(geyser,package="MASS")
g13 <- ggplot() +
geom_point(data=geyser, aes(x = duration, y = waiting)) +
geom_contour(data=geyser, aes(x = duration, y = waiting), colour="blue", size=.5, stat="density2d") +
xlim(0.5, 6) + scale_y_log10(limits=c(40,110)) +
ggtitle("geom_contour 2d density")
g13
``````