Spiral visualisation of time series data

802 views
Skip to first unread message

Tony Hirst

unread,
Feb 17, 2012, 12:10:09 PM2/17/12
to ggp...@googlegroups.com
I've just been tinkering with a few ways of visualising Twitter timeline data using ggplot ( http://blog.ouseful.info/2012/02/17/visualising-twitter-user-timeline-activity-in-r/ ) and as I was doing so, I was reminded of the use of interactive spirals as a technique for seeking periodicity, as in http://eagereyes.org/techniques/spirals

Leaving aside interactive features (for the moment?!;-), is there a documented way of generating an N-sided spiral over eg day binned time series data using ggplot2?

thanks
tony

Jean-Olivier Irisson

unread,
Feb 22, 2012, 5:47:54 PM2/22/12
to Tony Hirst, ggp...@googlegroups.com
On 2012-Feb-17, at 18:10 , Tony Hirst wrote:
>
> I've just been tinkering with a few ways of visualising Twitter timeline data using ggplot ( http://blog.ouseful.info/2012/02/17/visualising-twitter-user-timeline-activity-in-r/ ) and as I was doing so, I was reminded of the use of interactive spirals as a technique for seeking periodicity, as in http://eagereyes.org/techniques/spirals
>
> Leaving aside interactive features (for the moment?!;-), is there a documented way of generating an N-sided spiral over eg day binned time series data using ggplot2?

There is no pre-made method but you can get close enough with geom_tile in polar coordinates. It is close visually, but not a spiral (it is just rows of values, to get a spiral, one should compute the coordinates of each tile so that they slightly increase in y direction). Here is a "reproduction" of http://eagereyes.org/techniques/spirals with the devel version of ggplot2 (polar coordinates behave differently in the release version):


# get the devel version of ggplot2
library("devtools")
install_github("ggplot2")
library("ggplot2")


# Idea from
# http://eagereyes.org/techniques/spirals
# Data from
# http://www.dartmouth.edu/~chance/teaching_aids/data/birthday.txt

d <- read.table("http://www.dartmouth.edu/~chance/teaching_aids/data/birthday.txt", col.names=c("date", "n"))
# create a time coordinate easier to work with
d$day <- seq(from=0, along.with=d$date)
# NB: the plot will only work with a regular time coordinate so if that's not the case, then you should bin the time series beforehand

# plot the series, just to check
qplot(day, n, data=d, geom="path")

# period to test
p <- 21

# remove period from time coordinate
d$x <- d$day %% p

# compute number of periods elapsed
d$y <- floor(d$day / p)

# "bar" version
pBar <- ggplot(d) +
# plot tiles of the appropriate colour
geom_tile(aes(x=x, y=y, fill=n)) +
# use approximately the same colours as on the website
scale_fill_continuous(low="white", high="blue", space="rgb") +
# remove extra space and y breaks
scale_x_continuous(expand=c(0,0)) + scale_y_continuous(expand=c(0,0), breaks=NA)
print(pBar)

# "spiral" version
yMax <- max(d$y)
pBar +
# switch to polar coord, starting from -pi/2, going anticlockwise
coord_polar(start=-pi/2, direction=-1) +
# add extra blank space in the center of the spiral
scale_y_continuous(expand=c(0,0), breaks=NA, limits=c(-yMax/5, yMax)) +
# force the x coordinate (otherwise, NA appear for some reason)
scale_x_continuous(expand=c(0,0), limits=c(0,p))


# You can even get some interactivity if you are using RStudio (which is the second best thing that happened to R after ggplot2)

# package the code into a function
ggspiral <- function(x, y, p) {

# remove period from time coordinate
xx <- x %% p

# compute number of periods elapsed
yy <- floor(x / p)

# prepare data
d <- data.frame(xx, yy, y)
yyMax <- max(yy)

require("ggplot2")
ggplot(d) +
# plot tiles of the appropriate colour
geom_tile(aes(x=xx, y=yy, fill=y)) +
# switch to polar coord, starting from -pi/2, going anticlockwise
coord_polar(start=-pi/2, direction=-1) +
# add extra blank space in the center of the spiral
scale_y_continuous(expand=c(0,0), breaks=NA, limits=c(-yyMax/5, yyMax)) +
# force the x coordinate (otherwise, NA appear for some reason)
scale_x_continuous(expand=c(0,0), limits=c(0,p))
}

library("manipulate")
manipulate(ggspiral(d$day, d$n, p), p=slider(10,50))


I hope this helps.

Jean-Olivier Irisson
---
Observatoire Océanologique
Station Zoologique, B.P. 28, Chemin du Lazaret
06230 Villefranche-sur-Mer
Tel: +33 04 93 76 38 04
Mob: +33 06 21 05 19 90
http://jo.irisson.com/

Jean-Olivier Irisson

unread,
Feb 22, 2012, 6:09:42 PM2/22/12
to Tony Hirst, ggp...@googlegroups.com
On 2012-Feb-22, at 23:47 , Jean-Olivier Irisson wrote:
>
> It is close visually, but not a spiral (it is just rows of values, to get a spiral, one should compute the coordinates of each tile so that they slightly increase in y direction).

Actually, getting the spiral isn't that hard; geom_rect does the job. Hurray for ggplot!

d <- read.table("http://www.dartmouth.edu/~chance/teaching_aids/data/birthday.txt", col.names=c("date", "n"))
# create a time coordinate easier to work with
d$day <- seq(from=0, along.with=d$date)
# NB: the plot will only work with a regular time coordinate so if that's not the case, then you should bin the time series beforehand

# Implementation of a true spiral with geom_rect


ggspiral <- function(x, y, p) {

# remove period from time coordinate
xx <- x %% p

dt <- x[2] - x[1]
xx2 <- xx + dt

# compute number of periods elapsed

yy <- x / p
yy2 <- yy + 1

# prepare data
d <- data.frame(xx, xx2, yy, yy2, y)
yyMax <- max(yy2)

require("ggplot2")
ggplot(d) +
# plot tiles of the appropriate colour

geom_rect(aes(xmin=xx, xmax=xx2, ymin=yy, ymax=yy2, fill=y)) +


# switch to polar coord, starting from -pi/2, going anticlockwise
coord_polar(start=-pi/2, direction=-1) +
# add extra blank space in the center of the spiral
scale_y_continuous(expand=c(0,0), breaks=NA, limits=c(-yyMax/5, yyMax)) +
# force the x coordinate (otherwise, NA appear for some reason)
scale_x_continuous(expand=c(0,0), limits=c(0,p))
}

# in RStudio only


library("manipulate")
manipulate(ggspiral(d$day, d$n, p), p=slider(10,50))

Reply all
Reply to author
Forward
0 new messages