This is my first attempt at a TidyTuesday dataset. TidyTuesday is a weekly data project aimed at the R ecosystem. This week we got the Netflix dataset. Here, I am trying to observe how Netflix shows have expanded beyond border to have movies/TV shows from across the globe.
The Outcome
Netflix got shows from almost all over world. No wonder, everyone finds something for themselves.
Tips i.e. challenges I faced doing it
Many shows have been produced from multiple countries. I separate_rows function can be a life-saver in this type of scenario
countrycode is a handy little package to clean up all those pesky country naming conventions
Spatial objects of sf class are more convenient and memory efficient compared to sp class. Although, gganimate is more open to sp class (I am looking at you transition_reveal). Example- The same animation I tried with sp. It created an object with 400K+ elements. It ran for more than an hour and clogged my 16GB RAM the whole time.
In animate function, use bg parameter to match the canvas color to your plot to have a more consistent graphs.
Full Code
### Load libraries
# Data wrangling
library(tidyverse)
library(lubridate)
# Tidy Tuesday datasets
library(tidytuesdayR)
# World maps
library(rnaturalearth)
library(rnaturalearthdata)
# Animation
library(gganimate)
### Get TidyTuesay data
tt_data<-tt_load('2021-04-20')
netflix<-tt_data$netflix_titles
### Clean up an wrangle data with one lengthy pipe
df<-netflix%>%
mutate(
date_added_proper=lubridate::mdy(date_added)
)%>%
group_by(year=floor_date(date_added_proper,"year"),country)%>%
summarize(
count=n()
)%>%
ungroup()%>%
separate_rows(country,sep = ",")%>%
mutate(
country=str_trim(country)
)%>%
group_by(year,country)%>%
summarize(
count=n()
)%>%
ungroup()%>%
filter(country!='NA',country!="" )%>%
arrange(year,desc(count))%>%
mutate(
iso2=countrycode::countryname(country,destination = "iso2c"),
iso3=countrycode::countryname(country,destination = "iso3c"),
year=year(year)
)
### Getting it to maps
# Get map of the world
wmap<-ne_countries(scale = "medium",returnclass = "sf")
# Joining with spatial data
wmap_df<-wmap%>%
left_join(df,by=c('iso_a3'='iso3'))
# Animation layer - Took a long time to find the most efficient way to animate
wmap_df_anim<-wmap_df%>%
filter(!is.na(year))%>%
group_by(iso_a3)%>%
slice(which.min(year))%>%
ungroup()%>%
arrange(year)
### Plotting the static map
p<-wmap_df_anim%>%
ggplot()+
geom_sf(data=wmap_df%>%select(-year),lwd=0.2)+
geom_sf(fill='#74020B',lwd=0.2)+
geom_text(aes(x=75,y=-50,label= paste0(floor(year))),
size=15,color='#74020B')+
theme_minimal()+
labs(
title = "Netflix shows from Countries",
caption = "Plot by Saif Kabir Asif | saifkabirasif.com "
)+
theme(
plot.title=element_text(color='#838383',hjust=0.5,size=18,
face='bold'),
plot.caption=element_text(color='gray',face='italic',size=8),
plot.background = element_rect(fill='black'),
panel.background = element_rect(fill='black'),
legend.position = "none",
axis.title = element_blank(),
axis.text = element_blank(),
panel.grid=element_blank()
)
p
### Animating
p_anim<-p+transition_time(year)+shadow_mark(exclude_layer = 3)+
exit_disappear()
animate(p_anim,duration=30 ,
fps=15,
start_pause=15,
end_pause = 15,
detail=3,
bg='black',
type='cairo',
renderer = gifski_renderer(),
width=800,
height=450
)
### Save animation
anim_save(filename = paste0("Netflix_",Sys.Date(),".gif"),animation = last_animation())
Sharing is caring. Share this story in...
Share: Twitter Facebook LinkedIn Pocket Flipboard