How to create plots with beautiful animation using gganimate. | by Brian Mwangi. | Towards Data Science

Introduction.
The most important thing about visualization is when it forces us to realize something we didn’t know. Visually appealing charts easily draw our attention. Animating data is like breathing life into dust, it’s an act of creation. How do you create appealing animations that are insightful?
In this article, we are going to learn how to create beautiful animations using R package, gganimate.
#stable version of the package can be installed using install.packages(“gganimate”) #latest development version can be obtained by devtools::install_github(“thomasp85/gganimate”).
Data.
The Suicide Rate data is obtained from Kaggle after being compiled from different sources (WHO, UNDP, World Bank). The data compares socio-economic info with suicide rates per country from 1985 to 2016. The inspiration was to come up with suicide preventing strategies across the various countries.
Data Wrangling.
We are going to use the following code to clean the data and subset only the columns we are going to work with.
#loading required librarieslibrary(tidyverse)library(reshape2)library(ggthemes)library(gganimate)library(gifski)#loading datasetsuicide_data<-read.csv("./ARTICLES/suicide rates/master.csv",header = TRUE,stringsAsFactors = FALSE)#selecting columns to work withsuicide_sub<-suicide_data %>% select("ï..country","year" ,"sex","suicides_no")  %>% rename("country"="ï..country" )#function to sum the total suicide per countryn<-unique(suicide_sub$country)country<-function(x){  suicide2<-suicide_sub %>% filter(country==x)  sum(suicide2$suicides_no)}#return a list with all total deaths per countrycountry_total<-sapply(n,function(x) country(x))#creating a dataframe with top 10 total suicides per countrydf<-do.call(rbind,Map(data.frame,Country=n,Total_Suicides=country_total))df2<-df %>% arrange(desc(Total_Suicides))df3<-head(df2,n=10)write.csv(df3,"./ARTICLES/suicide rates/total_suicide.csv")#plotting the top 10 countries leading in the total suicide ratesggplot(df3,aes(reorder(Country,Total_Suicides),Total_Suicides,fill=as.factor(Country)))+    geom_col()+    coord_flip(clip = "off", expand = FALSE)+    guides( fill = FALSE) +    labs(title="TOTAL SUICIDE DEATHS PER COUNTRY FROM 1985-2016",          y="Total Suicides Per Country", x="Country")+    scale_y_continuous(labels = scales::comma) +     geom_text(aes(label = paste(Total_Suicides,"")), hjust = 1)
#subset initial data with top 10 countriestop_suicide<-suicide_sub%>%filter(country==c(“Russian Federation”,”United States”,”Japan”,”France”,”Ukraine”,”Germany”,”Republic of Korea”,”Brazil”,”Poland”,”United Kingdom”))#filtering years with consistent datatop_suicide2<-top_suicide %>% filter(year %in%c(1990:2014)) top_suicide2$sex<-as.factor(top_suicide2$sex)#summing the total male & female suicides per country for each yearsm3<-aggregate(suicides_no~country+year,top_suicide2,sum)#* 1 ensures we have non-integer ranks while slidingsm4<-sm3 %>% group_by(year) %>% mutate(rank = min_rank(-suicides_no) * 1) %>% ungroup()
Building static plots.
Our data is now ready for plotting. We are not going to dive into more details of using ggplot. A comprehensive guide on using ggplot can be obtained here.
#plotting static plotstatic_plot<-ggplot(sm4,aes(rank,group=country,fill=as.factor(country),color=as.factor(country))) + geom_tile(aes(y = suicides_no/2, height = suicides_no, width = 0.9), alpha = 0.8, color = NA) + geom_text(aes(y = 0, label = paste(country, “ “)), vjust = 0.2, hjust = 1) + geom_text(aes(y=suicides_no,label = paste(“ “,suicides_no)), hjust=0)+ coord_flip(clip = “off”, expand = TRUE) + scale_y_continuous(labels = scales::comma) + scale_x_reverse() + guides(color = FALSE, fill = FALSE) + theme_minimal() + theme( 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”), axis.ticks.y = element_blank(),  axis.text.y = element_blank(),  plot.margin = margin(1,1,1,4, “cm”) )
Animation.
What are the key features of gganimate?
1. transition_ *: this function defines how data should be spread and how it relates to itself over time.
a. transition_reveal: this allows you to let the data gradually disappear.
b. transition_time: the transition length between the states is set to correspond to the actual time difference between them.
c. transition_state: this is used to animate the plots by categorical or discrete variables.
2. view_ *: It is used to define how the axes should change along with the animation.
a. view_follow(fixed_y=TRUE): This means that the y_axis would be fixed when the animation is running.
b. view_follow(fixed_x=TRUE) : the x-axis would be fixed as the animation runs.
3. ease_aes(): it describes how the different aesthetics should be eased during animation.
a. ease_aes(“cubic-in-out”)
b. ease_aes(“sine-in-out”)
4. enter_*/exit_ *: it is used to determine how new data should be appearing and old data disappearing during the animation process.
a. enter_fade/exit_shrink
5. State_length: this refers to the relative length of pause of the states.
6. transition_length: this is the relative length of the animation.
#creating final animationplt<-static_plot + transition_states(states = year, transition_length = 4, state_length = 1) +  ease_aes(‘cubic-in-out’) + #view_follow(fixed_x = TRUE) + labs(title = ‘Total Suicides per Year : {closest_state}’,  subtitle = “Top 10 Countries”, caption = “Data Source: World Bank Data”, x=”Countries”,y=”Total Suicides per year”)
7. Rendering.
This is a kind of computing to output the final result. Parameters used include:
nframes: it sets the number of frames to be used (default is 100).
Frames per second(fps): this is the amount of time spent on each frame per second(default is 10)
Renderer: this sets the function for combining each frame into an animate. (defaults to gifski_renderer()).
If we want to end the loop we use: renderer= gifski_renderer(loop=FALSE) To save the animated plots as videos we use renderer=ffmpeg_renderer()
8. Duration This is the total time taken by the frames to animate i.e. duration=30
9. Layout.
We can change the height and width of our plot by specifying the size
We save the animation output to an object called final_animation.
#rendering the animation for giffinal_animation<-animate(plt,100,fps = 20,duration = 30, width = 950, height = 750, renderer = gifski_renderer())#rendering the animation for mp4animate(plt,100,fps = 20,duration = 30, width = 950, height = 750, renderer = ffmpeg_renderer())
10. Saving animation.
To save our animation we are going to use the function anim_save() with the parameters:
Animation-this is the final output of our animation plot.
Path-where we want our animation to be saved.
#saving the animationanim_save(“./ARTICLES/suicide rates/suicide_animate.gif”,animation=final_animation)
Output.
Conclusion.
We have been able to animate the suicide rates per country using R gganimate package. You can tweak the code to effectively animate any set of dataset and incorporate in your own presentations, blogs or website. For more insights on creating animations, you can check out this StackOverflow guide or Towards Data Science article. Feel free to comment, share and like. For more discussion, you can contact me via Linkedln.