Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animate ggplot2 stacked line chart in R

I'm trying to animate a stacked line chart in ggplot2.

Here's the plot I'd like to animate: enter image description here

Here's the code to generate a similar plot:

#Data
mydata <- data.frame(year=rep(1:6, times=4),
                 activity=as.factor(rep(c("research","coursework","clinical work","teaching"), each=6)),
                 time=c(40, 35, 40, 60, 85, 90,
                        50, 40, 10, 0, 5, 0,
                        5, 20, 20, 40, 10, 10,
                        5, 5, 30, 0, 0, 0))

mydata$activity <- ordered(mydata$activity, levels = c("research","clinical work","coursework","teaching"))

labels <- data.frame(activity=c("research","coursework","clinical work","teaching"),
                 xaxis=c(5, 1.8, 2.5, 2.97),
                 yaxis=c(25, 70, 48, 90))

#Plot
ggplot(mydata, aes(x=year, y=time, fill=activity)) +
  geom_area(stat="smooth", span=.35, color="black") +
  theme(legend.position = "none") +
  geom_text(data=labels, aes(x=xaxis, y=yaxis, label=activity)) +
  ggtitle("Time in Different Activities by Year in Program") +
  ylab("Percentage of Time") +
  xlab("Year in Program")

I'm looking for the first image to display all axes and text. The second iteration, I'd like to gradually reveal over time, from left to right, the "Research" stacked line (including color and border). The third iteration, I'd like to gradually reveal, from left to right, the "Clinical Work" stacked line. Fourth, the "Coursework" stacked line. And finally, the "Teaching" stacked line.

Ideally, the output format would be very smooth (no jagged jumps) and would be compatible with PowerPoint.

like image 455
itpetersen Avatar asked Dec 29 '25 21:12

itpetersen


2 Answers

Here is an R-based solution. It saves individual figures (.png) that can be iterated through within a presentation.

Alternatively,you could create an animation (for example converting to .gif) using ImageMagick http://www.imagemagick.org/

#Data
mydata <- data.frame(year=rep(1:6, times=4),
                     activity=as.factor(rep(c("research","coursework","clinical work","teaching"), each=6)),
                     time=c(40, 35, 40, 60, 85, 90,
                            50, 40, 10, 0, 5, 0,
                            5, 20, 20, 40, 10, 10,
                            5, 5, 30, 0, 0, 0))

#order the activities and then the dataframe
mydata$activity <- ordered(mydata$activity, levels = c("research","clinical work","coursework","teaching"))
mydata <- mydata[order(mydata$activity),]

#labels
labels <- data.frame(activity=c("research","coursework","clinical work","teaching"),
                     xaxis=c(5, 1.8, 2.5, 2.97),
                     yaxis=c(25, 70, 48, 90))

#creates a function to draws a plot for each activity
draw.stacks<-function(leg){
  int <- leg*6
  a<-ggplot(data=mydata[1:int,], aes(x=year, y=time, fill=activity))+
    geom_area(stat="smooth", span=.35, color="black") +
    theme_bw()+
    scale_fill_discrete(limits = c("research","clinical work","coursework","teaching"), guide="none")+
    theme(panel.grid.major = element_blank(),
          panel.grid.minor = element_blank()) +
    coord_cartesian(xlim=c(1,6),ylim=c(0,100))+
    geom_text(data=labels, aes(x=xaxis, y=yaxis, label=activity)) +
    ggtitle("Time in Different Activities by Year in Program") +
    ylab("Percentage of Time") +
    xlab("Year in Program")  
  print(a)
}


# save individual png figures
for (i in 0:4) {
png(paste("activity", i, "png", sep="."))
  draw.stacks(i)
dev.off()
}
like image 57
jNephin Avatar answered Jan 01 '26 11:01

jNephin


Sorry for bringing in a non-programmer solution, but I would simply generate plots for each iteration separately, put them in power point (one plot on one slide), and use some fancy slide transition effects (I tried the Random Bars effect on your example, and it looked nice).

If you determined to find an R-based solution, you can take a look at the animate package (see a Strategic Zombie Simulation example here).

like image 29
Marat Talipov Avatar answered Jan 01 '26 13:01

Marat Talipov