Search code examples
rggplot2gganimate

How to Make animated ggplot for different years using gganimate


So I have a simple data frame where the first column includes roadway IDs and the next 10 columns have traffic volumes on each roadway ID over 10 years.
I have been trying to come up with a code to display roadway ID on X axis and Traffic volume on Y axis. Then animate the graph over multiple years (Traffic volumes on the Y axis change). Here is a sample of my data frame:

Sample Data

Could anyone suggest a piece of code to do it? Here is a code that I have written but doesn't really work. I know this may be very wrong, but I am very new to gganimate and not sure how I can get different functions to work. Any help is appreciated.

year <- c(2001,2002,2003,2004,2005,2006,2007,2008,2009,2010)

p1 <- ggplot(data = Data) +
    geom_point(aes(x = Data$LinkIDs, y=Data$Year2001Traffic)) +
    geom_point(aes(x = Data$LinkIDs, y=Data$Year2002Traffic)) +
    geom_point(aes(x = Data$LinkIDs, y=Data$Year2003Traffic)) +
    geom_point(aes(x = Data$LinkIDs, y=Data$Year2004Traffic)) +
    geom_point(aes(x = Data$LinkIDs, y=Data$Year2005Traffic)) +
    geom_point(aes(x = Data$LinkIDs, y=Data$Year2006Traffic)) +

    geom_point(aes(x = Data$LinkIDs, y=Data$Year2007Traffic)) +  
    geom_point(aes(x = Data$LinkIDs, y=Data$Year2008Traffic)) +
    geom_point(aes(x = Data$LinkIDs, y=Data$Year2009Traffic)) +
    geom_point(aes(x = Data$LinkIDs, y=Data$Year2010Traffic)) +
  labs(title = 'Year: {frame_time}', x = 'Link ID', y = 'Traffic Volume') +  
  transition_time(year)

animate(p1)

Solution

  • Most of the work lies in changing the data before you send it to ggplot and gganimate. To help you with that work, I have created some sample data based on your picture (in the future please supply sample data yourself).

    library(tidyverse)
    library(gganimate)
    
    df <- tribble(
      ~LinkIDs, ~Year2001Traffic, ~Year2002Traffic, ~Year2003Traffic,
      "A", 1, 10, 15,
      "B", 3, 1, 10,
      "C", 10, 5, 1)
    df
    # A tibble: 3 x 4
      LinkIDs Year2001Traffic Year2002Traffic Year2003Traffic
      <chr>             <dbl>           <dbl>           <dbl>
    1 A                     1              10              15
    2 B                     3               1              10
    3 C                    10               5               1
    

    gganimate and ggplot work best with data in long format. So the first step is to change the data from wide to long before sending it to ggplot.

    df <- df %>% gather(Year, Traffic, -LinkIDs)
    df
    # A tibble: 9 x 3
      LinkIDs Year            Traffic
      <chr>   <chr>             <dbl>
    1 A       Year2001Traffic       1
    2 B       Year2001Traffic       3
    3 C       Year2001Traffic      10
    4 A       Year2002Traffic      10
    5 B       Year2002Traffic       1
    6 C       Year2002Traffic       5
    7 A       Year2003Traffic      15
    8 B       Year2003Traffic      10
    9 C       Year2003Traffic       1
    

    gganimate needs the Year column to be a number before it can use it for animation. So we need to extract the numbers that are contained in the values.

    df <- df %>% mutate(
      Year = parse_number(Year))
    df
    # A tibble: 9 x 3
      LinkIDs  Year Traffic
      <chr>   <dbl>   <dbl>
    1 A        2001       1
    2 B        2001       3
    3 C        2001      10
    4 A        2002      10
    5 B        2002       1
    6 C        2002       5
    7 A        2003      15
    8 B        2003      10
    9 C        2003       1
    

    Now the rest is straightforward. Just the plot the data, and use the year variable for the animation argument.

    p1 <- ggplot(df, aes(x = LinkIDs, y = Traffic))+
      geom_point()+
      labs(title = 'Year: {frame_time}', x = 'Link ID', y = 'Traffic Volume')+
      transition_time(Year)
    
    animate(p1)
    

    enter image description here

    _________________________ EDIT AFTER UPDATED COMMENTS_______
    Request in comments:

    "I just want it to go through the timeline (from 2001 to 2003) just once and then stop at 2003."

    In case you want to stop at the year 2003, you would need to filter the data before you send it to ggplot - this is done via the filter command.
    As of 23/3 2019, the is, as far as I know, no way to go through the animation just once. You can alter the end_pause argument in order to insert a pause after each iteration of the animation (I changed geom_point() to geom_col() given your description).

    p2 <- df %>% 
      #keep only observations from the year 2003 and earlier
      filter(Year <= 2003) %>% 
      #Send the data to plot
      ggplot(aes(x = LinkIDs, y = Traffic, fill = LinkIDs))+
      geom_col()+
      labs(title = 'Year: {frame_time}', x = 'Link ID', y = 'Traffic Volume')+
      transition_time(Year)  
    
    animate(p2, fps = 20, duration = 25, end_pause = 95)
    

    enter image description here