Creating Smooth Animations in R with tweenr (Traffic Speed Data)

While looking for libraries to create animated plots, I found this gem. I thought this was new but it looks like it s been there for a while. Tweenr library makes your gganimate transitions smoother by including more frames in between. I will show an example below.

Since I am a transportation engineer, I wanted to download some traffic data. Therefore, I used Caltrans PEMS tool. I downloaded traffic data for 3 days including Feb 5th, 7th and 9th — Monday, Wednesday, and Friday respectively. I wanted to show my students the change in speed for 3 different days. First let’s load our libraries:

library("utils")  
library("tweenr")
library("gganimate")
library("ggplot2")

After loading the required libraries, I loaded three different data frames including the downloaded data sets. Please keep in mind that these codes are shown in a class, thus, some codes are not practical. The aim was to make them as easy as possible.

Filename1 <- "../Data/d04_text_station_5min_2018_02_05.txt.gz"
Filename2 <- "../Data/d04_text_station_5min_2018_02_07.txt.gz"
Filename3 <- "../Data/d04_text_station_5min_2018_02_09.txt.gz"

PeMS1 <- read.delim(gzfile(Filename1), sep="," ,header=FALSE)
PeMS2 <- read.delim(gzfile(Filename2), sep="," ,header=FALSE)
PeMS3 <- read.delim(gzfile(Filename3), sep="," ,header=FALSE)

I selected one loop detector station specifically located on I80 with ID 400340

# Selection a loop detector station with a given ID, for instance SelectedID=400340 (lanes=4)
SelectedID <- 400340
StationData1 <- subset(PeMS1,PeMS1 [,2]==SelectedID)
StationData2 <- subset(PeMS2,PeMS2 [,2]==SelectedID)
StationData3 <- subset(PeMS3,PeMS3 [,2]==SelectedID)
StationData1$V1 <- as.POSIXlt(StationData1$V1, format="%m/%d/%Y %H:%M:%S")
StationData2$V1 <- as.POSIXlt(StationData2$V1, format="%m/%d/%Y %H:%M:%S")
StationData3$V1 <- as.POSIXlt(StationData3$V1, format="%m/%d/%Y %H:%M:%S")
StationData1$st <- "Monday"
StationData2$st <- "Wednesday"
StationData3$st <- "Friday"
StationData1$colour <- "red"
StationData2$colour <- "blue"
StationData3$colour <- "green"

I also defined two columns: one for defining the day of the data another one to define the color that will be required by the library. I realized I should add one more column to make the time axis look nicer:

StationData1$tt <- StationData1$V1$hour + StationData1$V1$min/60
StationData2$tt <- StationData2$V1$hour + StationData2$V1$min/60
StationData3$tt <- StationData3$V1$hour + StationData3$V1$min/60

Now, it is time to use tweenr library. The code to combine these 3 datasets using the package for a linear transition with 300 frames is:

data <- tween_states(list(StationData1, StationData2, StationData3), 3, 1, 'linear', 300)

If you go ahead and plot this with ggplot, you will see this:

ggplot(data, aes(tt,V12,  size = V10, colour=V10, frame = .frame)) +
geom_point(alpha=0.8) + xlab("Time (24 Hours)")+ylab("Speed (mph)")+
xlim(0,24)+
ylim(0,100)+
scale_colour_gradient(low="blue", high="red",guide="legend")
ggplot

The rest is on the gganimate package. Tweenr package will only create the points to make the transition smoother.

tweenr+gganimate

It is so obvious that some kind of breakdown (accident maybe?) happened on Wednesday when speed values drop down to 40–50 mph around 3 PM.

This may not be clear for some, if you have some questions please let me know.

Lead Traffic Modeler @Ulteig