Created
December 13, 2017 16:20
-
-
Save AdamSpannbauer/6fda7fd5cc6b876eb581767ec8170e03 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library(data.table) | |
library(gganimate) | |
library(ggplot2) | |
#toy example data | |
dt = data.table(time=1:10, x=round(runif(10, 50, 100), 0)) | |
#number of frames per bar | |
n_frames_per_bar = 20 | |
#create sequence per time (to imitate the bar growing from ground) | |
split_dt = split(dt, dt$time) | |
split_dt_fill = lapply(split_dt, function(dti) { | |
#create sequence of length n per bar for animation | |
data.table(time=dti$time, x=seq(1, dti$x, length.out = n_frames_per_bar)) | |
}) | |
dt_fill = rbindlist(split_dt_fill) | |
#id each row as its own frame | |
dt_fill[,frame := 1:.N] | |
#once a bar is grown it needs to stay there | |
#fill in historical bars at full height in future time periods | |
split_dt_fill2 = split(dt_fill, dt_fill$time) | |
split_dt_fill2_backfill = lapply(split_dt_fill2, function(dti){ | |
#get time i | |
time_i = unique(dti$time) | |
#make bar for time i a different color | |
dti[,fill := "time i"] | |
#backfill bar heights if there is history to fill in | |
if (time_i > 1) { | |
#get max bar height for all historical bars | |
backfill_dt = dt_fill[time < time_i,][order(-frame), .SD[1], by=time][,.(time,x)] | |
#create a row of max height for each frame in time i | |
split_backfill_dt = split(backfill_dt, backfill_dt$time) | |
split_backfill_dt = lapply(split_backfill_dt, function(dtj){ | |
data.table(time=dtj$time, x=dtj$x, frame=dti$frame) | |
}) | |
backfill_dt = rbindlist(split_backfill_dt) | |
#label fill group for coloring bars | |
backfill_dt[,fill := "historical"] | |
out = rbind(dti, backfill_dt) | |
} else { | |
out = dti | |
} | |
out | |
}) | |
plot_dt = rbindlist(split_dt_fill2_backfill) | |
#plot (using gganimate's frame arg in aes) | |
p = ggplot(plot_dt, aes(x=time, y=x, frame=frame, fill=fill)) + | |
geom_bar(stat="identity", position = "identity") + | |
scale_fill_manual(values=c("steelblue", "steelblue1")) + | |
guides(fill=FALSE) + | |
labs(x="Time", y="Value", title="") | |
#create gif (using interval to specify the time per frame) | |
gganimate(p, title_frame = FALSE, interval = .001) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As others have said, you should package it! Thanks so much