How to build Animated Bar Plots using R

[This article was first published on R Programming – DataScience+, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

    Categories

    1. Visualizing Data

    Tags

    1. Animation
    2. Data Visualisation
    3. R Programming

    Recently, Animated Bar Plots have started going Viral on Social Media leaving a lot of Data Enthusiasts wondering how are these Animated Bar Plots made. The objective of this post is to explain how to build such an Animated Bar Plot using R – R with the power of versatile packages.

    Final Output:

    The output of this project is going to look like this:

    Packages

    The packages that are required to build animated plots in R are:

    While those above two are the essential packages, We have also used the entire tidyverse, janitor and scales in this project for Data Manipulation, Cleaning and Formatting.

    Data

    The original dataset used for this project is downloaded from WorldBank Data. The same csv file can be found in the project folder.

    About Data:

    This data contains GDP value of most of the countries for several years (especially from 2000 to 2017).

    Data Preprocessing:

    We will use the following code to prepare our data in the desired format. Actually, we’re cleaning up the column names, typecasting the numbers into numeric format and converting the data from Wide Format to Long format using tidyr’s gather() function. The tidy data is saved into a new csv file gdp_tidy.csv for further usage.

    library(tidyverse)
    library(janitor)
    
    gdp <- read_csv("./data/GDP_Data.csv")
    
    #select required columns
    
    gdp <- gdp %>% select(3:15) 
    
    #filter only country rows
    
    gdp <- gdp[1:217,]
    
    gdp_tidy <- gdp %>% 
      mutate_at(vars(contains("YR")),as.numeric) %>% 
      gather(year,value,3:13) %>% 
      janitor::clean_names() %>% 
      mutate(year = as.numeric(stringr::str_sub(year,1,4)))
    
    write_csv(gdp_tidy,"./data/gdp_tidy.csv")
    
    
    

    Animated Plot

    An Animated Plot building process involves two primary sections:

    • Building the entire set of actual static plots using ggplot2
    • Animating the static plots with desired parameters using gganimate

    The final step after these two primary steps is to render the animation in the desired file format, like GIF or MP4 (Video).

    Loading Required Libraries

    library(tidyverse)
    library(gganimate)
    

    Data Manipulation:

    In this step, We’re going to filter our dataset to retain only the top 10 countries for every given year. We’ll also create a few more columns that will help us display labels in the plot.

    gdp_tidy <- read_csv("./data/gdp_tidy.csv")
    
    
    gdp_formatted <- gdp_tidy %>%
      group_by(year) %>%
      # The * 1 makes it possible to have non-integer ranks while sliding
      mutate(rank = rank(-value),
             Value_rel = value/value[rank==1],
             Value_lbl = paste0(" ",round(value/1e9))) %>%
      group_by(country_name) %>% 
      filter(rank <=10) %>%
      ungroup()
    

    Building Static Plots

    Now that our data is ready to plotted, We’ll build all the required static plots. As you might have seen in the animation at the top of this post, We’re going to see how the Top 10 Countries based on GDP has changed over the years in the given dataset. For that we need to build individual plots for each year.

    staticplot = ggplot(gdp_formatted, aes(rank, group = country_name, 
                    fill = as.factor(country_name), color = as.factor(country_name))) +
      geom_tile(aes(y = value/2,
                    height = value,
                    width = 0.9), alpha = 0.8, color = NA) +
      geom_text(aes(y = 0, label = paste(country_name, " ")), vjust = 0.2, hjust = 1) +
      geom_text(aes(y=value,label = Value_lbl, hjust=0)) +
      coord_flip(clip = "off", expand = FALSE) +
      scale_y_continuous(labels = scales::comma) +
      scale_x_reverse() +
      guides(color = FALSE, fill = FALSE) +
      theme(axis.line=element_blank(),
            axis.text.x=element_blank(),
            axis.text.y=element_blank(),
            axis.ticks=element_blank(),
            axis.title.x=element_blank(),
             axis.title.y=element_blank(),
            legend.position="none",
            panel.background=element_blank(),
            panel.border=element_blank(),
            panel.grid.major=element_blank(),
            panel.grid.minor=element_blank(),
            panel.grid.major.x = element_line( size=.1, color="grey" ),
            panel.grid.minor.x = element_line( size=.1, color="grey" ),
            plot.title=element_text(size=25, hjust=0.5, face="bold", colour="grey", vjust=-1),
            plot.subtitle=element_text(size=18, hjust=0.5, face="italic", color="grey"),
            plot.caption =element_text(size=8, hjust=0.5, face="italic", color="grey"),
            plot.background=element_blank(),
           plot.margin = margin(2,2, 2, 4, "cm"))
    

    We will not get into the details of how to static plots are built as that’s pretty much similar to how any normal plot is built using ggplot2. As you can see in the above code, There are a few key aspects with the theme() function that are done to make it go well with the animation, like – Only Vertical Grid Lines are drawn and Legends, Axes Title and few more components are removed from the plot.

    Animation

    The key function here is transition_states() which stitches the individual static plots together by year. view_follow() is used to give a view as if the background lines (gridlines) are moving as the animation is progressing.

    anim = staticplot + transition_states(year, transition_length = 4, state_length = 1) +
      view_follow(fixed_x = TRUE)  +
      labs(title = 'GDP per Year : {closest_state}',  
           subtitle  =  "Top 10 Countries",
           caption  = "GDP in Billions USD | Data Source: World Bank Data") 
    

    Rendering

    With the animation being built (ready) and saved in the object anim , It’s time for us to render the animation using animate() function. The renderer used in the animate() differs based on the type of output file required.

    For GIF File Format:

    # For GIF
    
    animate(anim, 200, fps = 20,  width = 1200, height = 1000, 
            renderer = gifski_renderer("gganim.gif")) 
    

    For Video (MP4) File Format:

    # For MP4
    
    animate(anim, 200, fps = 20,  width = 1200, height = 1000, 
            renderer = ffmpeg_renderer()) -> for_mp4
    
    anim_save("animation.mp4", animation = for_mp4 )
    

    Gives this Animation

    Summary

    Thus, We’ve successfully built the Animated Bar Plot to visualize how the Top Countries have moved over a few years period, based on its GDP value. This code can be easily modified to fit in your purpose once the data preprocessing and data manipulation steps take care of reshaping your input data into the desired format. R is an amazing tool for Data Visualization of any form and to learn more check out this. This entire project is available on my github, feel free to fork and use it for your use-case.

    Related Post

    1. How to combine Multiple ggplot Plots to make Publication-ready Plots
    2. Australian MP tweets collection and quick analysis
    3. Introducing vizscorer: a bot advisor to score and improve your ggplot plots
    4. Visualize your CV’s timeline with R (Gantt chart style)
    5. K-Means Clustering: Analysing City of London Traffic

    To leave a comment for the author, please follow the link and comment on their blog: R Programming – DataScience+.

    R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
    Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

    Never miss an update!
    Subscribe to R-bloggers to receive
    e-mails with the latest R posts.
    (You will not see this message again.)

    Click here to close (This popup will not appear again)