Analyzing Anime data in R. If you are a fan of Anime then you are... | by Hamza Rafiq | Towards Data Science

If you are a fan of Anime then you are going to love this analysis I did in R. This data comes from the MyAnimeList website and was sourced as part of the Tidy Tuesday initiative by the R for Data Science community. You can download a tidy version of this data from here. They post interesting datasets every week and the community shares their analyses, mostly using the Tidyverse set of packages which is a great source of learning. I would also suggest following David Robinson’s YouTube channel. He uploads new videos every week in which he analyzes a new dataset from Tidy Tuesday and you get to learn so many cool things from him.
As always, we will be loading some libraries.
library(tidyverse)# Data manipulation and visualizationlibrary(scales)# Converting data values to unitslibrary(patchwork) # For Patching multiple ggplots together
Use the read_csv function, I can read the data directly from the website by providing a link to the dataset for the file argument. After loading the data, lets take a look at the data using the View function
tidy_anime <- read_csv(file="https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2019/2019-04-23/tidy_anime.csv")View(tidy_anime)
As you can see, this is a huge dataset and I do not need all the columns for my analysis. If you look at the first screenshot, you will see that each Anime ID is getting duplicated. This is because each anime on the MyAnimeList website is categorized under different genres. So there is a row for each different genre for every single anime, hence the duplication. Same is the issue with the producers and studio columns, as one anime can have multiple producers and studios
tidy_anime <- tidy_anime%>%select(-c(title_synonyms,synopsis,background,related,genre,studio,producer))
To remove these columns I just wrap them up in a “-” together which is a way of deselecting.
unique_anime <- tidy_anime%>%distinct()%>%filter(!is.na(title_english))View(unique_anime)
We then use the distinct function so that we get a unique Anime ID for every single row. I am only interested in those with an English title so I remove any that are without them. Lets take another look at the data now.
Nice! now we have a unique Anime ID at every single row. We can now start analyzing our data.
If any of you are Anime fans, then you would know Anime TV shows and Anime movies should not be compared together. Both should be compared within their own categories. For this purpose, we will further split this data into TV and Movie category
tv_anime <- unique_anime%>%filter(type=="TV")tv_plot <-tv_anime%>%  mutate(graph_name=paste0(title_english," (",premiered,")"))%>%  top_n(-20,wt=popularity) %>%   ggplot(aes(reorder(graph_name,desc(popularity)),popularity,colour=title_english))+  geom_point(show.legend = FALSE)+  geom_segment(aes(x=graph_name,xend=graph_name,y=0,yend=popularity),show.legend = FALSE)+  coord_flip()+  theme_classic()+  labs(x="",y="Popularity",title = "Top 20 Most Popular Anime TV Shows")
Let's go through this code step by step:
I filter the date for only TV shows
In my graph, I also want to see when did they premier, so I created a new column — graph_name using the mutate function. Within the mutate function, I used the Paste0 function to combine title_english and premiered columns
Then I used top_n function to get the 20 most popular animes. Notice I used -20 because that would get the 20 lowest values and since this is a rank-based value, lowest values means the most popular
Then I used the standard ggplot function to plot our x and y-axis values. I used the reorder function on the x-axis because I wanted it to be sorted based on the popularity value
I am creating a lollipop chart and for that, I need to combine geom_point and geom_segment together to get my result. geom_point plots the points while goem_segment draws the line
coord_flip to make it vertical and other standard functions to label the plot and change the appearance of the theme.
Nothing surprising here. All of these shows are extremely popular but an interesting thing to note is that of all these shows are not currently airing hence shows like Once Piece and Bleach are not there. Let's take a look at the most popular shows that are currently airing
tv_anime_airing <- unique_anime%>%filter(type=="TV",airing=="TRUE")tv_plot_airing <-tv_anime_airing%>%  mutate(graph_name=paste0(title_english," (",premiered,")"))%>%  top_n(-20,wt=popularity) %>%   ggplot(aes(reorder(graph_name,desc(popularity)),popularity,colour=title_english))+  geom_point(show.legend = FALSE)+  geom_segment(aes(x=graph_name,xend=graph_name,y=0,yend=popularity),show.legend = FALSE)+  coord_flip()+  theme_classic()+  labs(x="",y="Popularity",title = "Top 20 Most Popular Anime TV Shows")+  theme(axis.text.y.left = element_text(size = 12))
The code is the same as before. I made a slight adjustment of filtering for shows that are currently airing
Ah! One Piece is on the top for shows that are currently airing. I am surprised One Punch Season 2 and Attack on Titan Season 3 (Part 2 ) are not here. Probably they didn't air when this data was collected. I have only watched Mob Psycho 100 out of these. Let's also take a look at the highest scored Animes.
Hmm kinda disappointing that most of these Animes are not even above a score of 8. Moving on, I am interested in looking at which popular animes scored high and what was their relationship with the number of people who scored for these anime
tv_anime %>%   filter(popularity <= 50) %>%  mutate(title_english = str_replace(title_english, "Code Geass: Lelouch of the Rebellion", "Code Geass")) %>%  ggplot(aes(score, scored_by)) +   geom_point(shape=21,aes(fill=title_english,size=members)) +   geom_text(aes(label = title_english ), check_overlap = T, show.legend = F, size = 3, hjust = 1) +   xlim(c(6, 10)) +  scale_y_log10()+  labs(title = "Which popular anime also score high?",        subtitle = "Top 50 anime shown based on popularity",       y = "Number of users that scored",       x = "Score (1-10)") +  theme_classic()+  theme(legend.position = 'none',aspect.ratio = 0.5)
Death Note at the top again. I would assume that Anime like Death Note, Attack on Titan, and Sword Art Online have a really loyal fan base who went to the website and scored for them. Shows like Once Piece have been on the air for quite a while but comparatively lesser people scored it.
Lets now take a look at Popularity vs Score. Are there any popular anime that didn't score high and vice versa.
tv_anime%>%  filter(popularity<=100) %>%   ggplot(aes(popularity,score,fill=rating))+  geom_point(shape=21,size=3,alpha=0.8)+  geom_text(aes(label=title_english),size=3,check_overlap = TRUE)+  scale_x_log10()+  theme_classic()+  scale_color_brewer(palette = 'Set1')+  theme(legend.position = "bottom")+  labs(title = "Popularity vs Score",subtitle = "Do all Popular Anime score high?")
So the most popular animes have definitely had the highest scores. Although the graph is filled with PG-13 rated shows, the top-scored animes are definitely R-17+. A bit surprised that My Hera Academia Season 2 & Season 3 are not as popular as the first even they both have a higher rating compared to the first season.
Finally, I would like to compare the top 20 most members vs most scored by and most favorites.
most_members <- tv_anime%>%  top_n(20,wt=members) %>%  mutate(graph_name=paste0(title_english," (",premiered,")"),graph_name=fct_reorder(graph_name,members))%>%  ggplot(aes(graph_name,members,fill=graph_name))+  geom_bar(stat = 'identity',width=0.5,show.legend = FALSE,color='black')+  coord_flip()+  theme_classic()+  scale_y_continuous(limits = c(0,1700000),labels = comma)+  geom_text(aes(label=comma(members)),size=3)+  labs(x="",y="Rank",title = "Top 20 Most Members")most_favorite<-  tv_anime%>%  top_n(20,wt=favorites) %>%   mutate(title_english=fct_reorder(title_english,favorites))%>%  ggplot(aes(title_english,favorites,fill=title_english))+  geom_bar(stat = 'identity',width=0.5,show.legend = FALSE,color='black')+  coord_flip()+  theme_classic()+  scale_y_continuous(limits = c(0,150000),labels = comma)+  geom_text(aes(label=comma(favorites)),size=3,hjust=1,fontface='bold')+  labs(x="",y="Favourites",title = "Top 20 Most Favorite")most_scored<-  tv_anime%>%  top_n(20,wt=scored_by) %>%   mutate(title_english=fct_reorder(title_english,scored_by))%>%  ggplot(aes(title_english,scored_by,fill= title_english))+  geom_bar(stat = 'identity',width=0.5,color='black',show.legend = FALSE)+  coord_flip()+  theme_classic()+  scale_y_continuous(limits = c(0,1500000),labels = comma)+  geom_text(aes(label=comma(scored_by)),size=3,hjust=1,fontface='bold')+  labs(x="",y="Favourites",title = "Top 20 Most Scored by")most_favorite + most_members+ most_scored + plot_layout(widths = 20)
Pretty obvious that anime with the most members would have more people scoring of it. I have never scored for an anime on MyAnimeList but I would assume from this that you need to become a member of that Anime in order to score for it. Most Favorites is a different story. This could potentially highlight the anime with the most loyal fan base who loved the anime so much that they added it to their favorites.
I hope you found this analysis interesting. In case you want to analyze Anime movies, you can use the same code but the only difference would be to just filter for Movies instead of TV.