Adam T. Bradley

Posts in category “visualization”

PaperJS Sparklines

Yet another PaperJS experiment. This one generates Sparklines. It simply looks for canvases matching a specific CSS selector (canvas.sparkler by default), and draws a chart based on JSON-formatted data in the data-data attribute. Here, I'm displaying some unemployment data from Quandl.

The code is on Gist.

library(rjson)
library(Quandl)

Quandl.auth(getOption('quandl_auth_key'))

ct.unemp <- Quandl("FRBC/UNEMP_ST_CT", trim_start="1978-01-01", trim_end="2013-12-01", collapse="monthly")
ct.2yunemp <- rev(ct.unemp$Value[1:24])

me.unemp <- Quandl("FRBC/UNEMP_ST_ME", trim_start="1978-01-01", trim_end="2013-12-01", collapse="monthly")
me.2yunemp <- rev(me.unemp$Value[1:24])

ma.unemp <- Quandl("FRBC/UNEMP_ST_MA", trim_start="1978-01-01", trim_end="2013-12-01", collapse="monthly")
ma.2yunemp <- rev(ma.unemp$Value[1:24])

nh.unemp <- Quandl("FRBC/UNEMP_ST_NH", trim_start="1978-01-01", trim_end="2013-12-01", collapse="monthly")
nh.2yunemp <- rev(nh.unemp$Value[1:24])

ri.unemp <- Quandl("FRBC/UNEMP_ST_RI", trim_start="1978-01-01", trim_end="2013-12-01", collapse="monthly")
ri.2yunemp <- rev(ri.unemp$Value[1:24])

vt.unemp <- Quandl("FRBC/UNEMP_ST_VT", trim_start="1978-01-01", trim_end="2013-12-01", collapse="monthly")
vt.2yunemp <- rev(vt.unemp$Value[1:24])
New England Unemployment by State, 2011-12-31 to 2013-11-30
State Min/max 2011-12-31 2013-11-30
Connecticut 7.5%/8.5% 8.3% 7.5%
Maine 6.4%/7.4% 7.4% 6.4%
Massachusetts 6.7%/7.2% 6.9% 7.1%
New Hampshire 5.2%/5.6% 5.4% 5.2%
Rhode Island 9.4%/10.9% 10.9% 9.4%
Vermont 4.2%/5.1% 5.1% 4.3%

Social Network Simulation with PaperJS

What it's doing: Each node has a belief that matches its hue, represented as an angle between 0 and 359 degrees. Every 25 frames (once a second or so), a node is chosen at random and given a choice whether to speak; if it does (this is represented by a fading circle expanding from the node). Every other node has a chance to hear the speaking node based on the distance between the speaker and the listener--the farther you are from the speaker, the less likely you are to hear.

Once a node does hear another node, it will only care about what it's hearing under one of two conditions:

  1. The hearer's beliefs (i.e. color) are similar to the speakers, in which case the hearer's beliefs will move slightly closer to the speaker's; or
  2. The hearer's beliefs are very different from the speakers, and its beliefs will move even further away from the speaker's.

In either case, there is a small chance the hearer will subscribe to the speaker, which adds a line between the two and means the hearer will always hear announcements from that speaker.

NB: This isn't designed--at least in this incarnation--to be a realistic simulation of anything. It's another experiment with PaperJS.

Word Hail

This is a minor experiment with Paper.js, made while I (re-)teach myself to animate color and movement. (Click through to view.)

Twin River Casino Votes

Same kinda map as yesterday, but this time I’m using the read.fwf function to pull election result data from the Rhode Island Board of Elections

library(maptools)
## Loading required package: foreign


## Loading required package: sp


## Loading required package: grid


## Loading required package: lattice


## Checking rgeos availability: FALSE Note: when rgeos is not available,
## polygon geometry computations in maptools depend on gpclib, which has a
## restricted licence. It is disabled by default; to enable gpclib, type
## gpclibPermit()
library(RColorBrewer)
library(classInt)
## Loading required package: class


## Loading required package: e1071

ri <- readShapePoly('../map/ri/towns.shp')
wds = c(4,3,4,6,6,6,6,6,6,3,3,4,56,38,30,25,2,1)
cls = c('contestNum', 'candidateNum',
'precinctCode', 'totalVotes',
'group1', 'group2', 'group3',
'group4', 'group5', 'partyCode',
'districtType', 'districtCode',
'contestTitle', 'candidateName',
'precinctName', 'districtName',
'votesAllowed', 'referendum')
riel = read.fwf('rigen2012l.asc',
wds, col.names = cls,
strip.white = TRUE)
towns <- sub('(\d+)', '', riel$precinctName)
towns <- sub('President', '', towns)
towns <- sub('Limited', '', towns)
towns <- sub('(\s+$)', '', towns)
riel$town <- towns
Q1 <- riel[riel$contestTitle==
'QUESTION 1 - TWIN RIVER CASINO',]
Q1 <- aggregate(Q1$totalVotes,
list(Q1$candidateNum, Q1$town), sum)
Q1 <- reshape(Q1, v.names="x", idvar="Group.2",
timevar="Group.1", direction="wide")
colnames(Q1) <- c('town', 'yes', 'no')
Q1$town = toupper(Q1$town)
Q1$pct.yes = Q1$yes/(Q1$yes+Q1$no)*100
pct.yes<-function(town){ Q1$pct.yes[Q1$town==town] }
ri@data$Q1support <- lapply(ri@data$NAME, pct.yes)
pvar <- as.numeric(ri@data$Q1support)
intrvs <- 9
colors <- brewer.pal(intrvs, 'Oranges')
class <- classIntervals(pvar, intrvs, style="equal")
colcode <- findColours(class, colors)
plot(ri, col=colcode)
title("Support for Twin River Casinon%
votes in support, November 2012")
legend('right', legend=names(attr(colcode, "table")),
fill=attr(colcode, "palette"))

Support for Twin River casino