After two years of launching, Genshin Impact has won several awards, such as “iPhone game of the year” in the Apple Store Best of 2020, Google Play’s Best of 2020, 2021 Apple Design Awards for Visuals and Graphics, and several other awards. Character design, clean combat mechanic, compelling storyline, regular update, breath-takingly beautiful and vast open world are some of the factors that contribute to the success of Genshin Impact in comparison to other competitors in the RPG gaming field. From around 20 playable characters and 1 explorable region at launch, the game has expanded to over 50 playable characters and 4 explorable regions as of now.
This analysis consists of 3 parts.
In the first part of this analysis, we are making some basic visualizations to understand the characters a bit better (Their origin, rarity, vision, weapon type, gender, birthday, …)
In the second part of this analysis, we are going to compare the stats of different characters based on their visions (elements), and based on their origins (nation). Hopefully, we would be able to see which element, and which region has a stronger character line-up compared to others. Up until now, there are 6 elements: Pyro, Hydro, Electro, Anemo, Cryo, Geo (with Dendro being introduced later), and 3 nations: Mondstadt, Liyue, Inazuma (with Sumeru being introduced later). The stats that we are using to compare would be Base HP, Base ATK and Base DEF
In the third part of this analysis, we are taking a slightly different approach on the banner sales. By looking into the banner sales, we might be able to get some interesting insights into the popularity of the game and the nations they introduced.
Installing tidyverse and ggplot2
install.packages("tidyverse")
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.1'
## (as 'lib' is unspecified)
library(tidyverse)
## ── Attaching packages
## ───────────────────────────────────────
## tidyverse 1.3.2 ──
## ✓ ggplot2 3.3.6 ✓ purrr 0.3.4
## ✓ tibble 3.1.6 ✓ dplyr 1.0.9
## ✓ tidyr 1.2.0 ✓ stringr 1.4.0
## ✓ readr 2.1.2 ✓ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
install.packages("ggplot2")
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.1'
## (as 'lib' is unspecified)
library(ggplot2)
These datasets have been manually collected and modified by me using Google Spreadsheet
genshin_dataset <- read_csv("/cloud/project/Genshin Analysis/Genshin Characters.csv")
## Rows: 52 Columns: 12
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (7): Character, Element, Weapon, Ascension, Gender, Nation, Birthday
## dbl (5): Lv, Rarity, Base HP, Base ATK, Base DEF
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
glimpse(genshin_dataset)
## Rows: 52
## Columns: 12
## $ Character <chr> "Albedo", "Aloy", "Amber", "Ayaka", "Ayato", "Barbara", "Be…
## $ Lv <dbl> 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,…
## $ Rarity <dbl> 5, 5, 4, 5, 5, 4, 4, 4, 5, 4, 4, 5, 4, 5, 4, 5, 4, 4, 5, 5,…
## $ Element <chr> "Geo", "Cryo", "Pyro", "Cryo", "Hydro", "Hydro", "Electro",…
## $ Weapon <chr> "Sword", "Bow", "Bow", "Sword", "Sword", "Catalyst", "Claym…
## $ Ascension <chr> "Geo DMG", "Cryo DMG", "ATK", "CRIT DMG", "CRIT DMG", "HP",…
## $ `Base HP` <dbl> 13226, 10899, 9461, 12858, 13715, 9787, 13050, 12397, 13103…
## $ `Base ATK` <dbl> 251, 234, 223, 342, 299, 159, 225, 191, 301, 223, 200, 335,…
## $ `Base DEF` <dbl> 876, 676, 601, 784, 769, 669, 648, 771, 815, 648, 601, 784,…
## $ Gender <chr> "Male", "Female", "Female", "Female", "Male", "Female", "Fe…
## $ Nation <chr> "Mondstadt", "Other", "Mondstadt", "Inazuma", "Inazuma", "M…
## $ Birthday <chr> "9/13", "4/4", "8/10", "9/28", "3/26", "7/5", "2/14", "2/29…
Checking column names:
colnames(genshin_dataset)
## [1] "Character" "Lv" "Rarity" "Element" "Weapon" "Ascension"
## [7] "Base HP" "Base ATK" "Base DEF" "Gender" "Nation" "Birthday"
In this first part of the analysis, we are going to explore the world of Teyvat by doing some fun and basic visualizations. These are going to be all BAR CHARTS and use count as the y-axis. The purpose of this part is to make myself more familiar with visualizing in R using ggplot2.
ggplot(data = genshin_dataset, mapping = aes(x = Weapon)) +
geom_bar(fill = "darkgoldenrod1", color = "white") +
geom_text(stat='count', aes(label=..count..), vjust=-0.1) +
labs(title = "Weapon type popularity",
x = "Weapon type",
y = "Number of Characters")
Up until this point, a lot of characters use bow as their weapons, while the number of claymore and polearm characters is pretty low.
Learned: add count number on each of the column
ggplot(data = genshin_dataset, mapping = aes(x = Element, fill = Element)) +
geom_bar(color = "white") +
scale_fill_manual(values = c("Anemo" = "aquamarine1",
"Cryo" = "cyan2",
"Dendro" = "chartreuse2",
"Pyro" = "red",
"Geo" = "darkorange3",
"Electro" = "purple",
"Hydro" = "blue")) +
geom_text(stat='count', aes(label=..count..), vjust=-0.1) +
labs(title = "Element popularity",
x = "Element",
y = "Number of Characters")
Cryo and Pyro visions are pretty popular at the moment (10 characters each), while Dendro roster is quite limited right now since Dendro has only been introduced to the game for less than a month.
Learned: Adjust the bar color manually using a vector
bd <- genshin_dataset$Birthday
library(lubridate)
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
m <- month(as.POSIXlt(bd, format="%m/%d"))
m <- m %>% replace(is.na(.), 2)
ggplot(data = genshin_dataset, mapping = aes(x = m)) +
geom_bar(fill = "darkgoldenrod1", color = "white") +
geom_text(stat='count', aes(label=..count..), vjust=-0.1) +
labs(title = "Birthday distribution",
x = "Month",
y = "Number of Characters")
There have been variations in the number of characters by their birth-months. However, it’s interesting that most of the characters were born in July (8 characters).
Learned: Extracting months from month-date format and store it in a temp value -> visualize it later
ggplot(data = genshin_dataset, mapping = aes(x = Gender, fill = Gender)) +
geom_bar(color = "white") +
scale_fill_manual(values = c("Male" = "blue",
"Female" = "red")) +
geom_text(stat='count', aes(label=..count..), vjust=-0.1) +
labs(title = "Gender Difference",
x = "Gender",
y = "Number of Characters")
Surprisingly, for this aspect, the number of female characters almost doubles the number of male characters up to this point (34 females vs. 18 males). This indicates a tremendous imbalance among the gender distribution of the game. Hopefully, in the future, Hoyoverse would introduce more male characters to resolve this.
Learned: Choose the color that usually indicates each gender (red + blue)
ggplot(data = genshin_dataset, mapping = aes(x = Nation, fill = Nation)) +
geom_bar(color = "white") +
scale_fill_manual(values = c("Mondstadt" = "aquamarine1",
"Liyue" = "darkorange3",
"Inazuma" = "purple",
"Sumeru" = "chartreuse2",
"Other" = "white")) +
geom_text(stat='count', aes(label=..count..), vjust = -0.1) +
labs(title = "Characters by Nation",
x = "Nation",
y = "Number of Characters")
It does seem that The earlier the nation is introduced to the game, the more characters it has. Since Mondstadt was introduced first, following by Liyue, Inazuma, and Sumeru respectively, we could confirm our hypothesis in the beginning. Hoyoverse did a good job keeping the character roster by nation quite balanced. With the recent introduction of Sumeru, we could expect that a lot more characters from this nation would be introduced into the game in the near future.
Learned: Practice using all skills learned above
We would be looking mostly at the ATK stats of characters to decide which character is the strongest. In addition, HP and DEF would be taken into consideration to see which character is the most tanky. The definition of “outstanding” here is quite arbitrary, since some characters might be scale by HP, DEF, or Energy Recharge to deal damage, and it might vary between users as some users prefer characters that deal big damage, some users prefer characters that deal accumulative damage from different small sources of damage, and some users even prefer characters that could endure lots of damages from enemies. Therefore, we would just look at different aspects of “outstanding” and deduce the conclusion based on the data.
if (!require("janitor")) install.packages("janitor")
## Loading required package: janitor
##
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
##
## chisq.test, fisher.test
library(janitor)
genshin_dataset <- clean_names(genshin_dataset)
genshin_dataset
## # A tibble: 52 × 12
## character lv rarity element weapon ascension base_hp base_atk base_def
## <chr> <dbl> <dbl> <chr> <chr> <chr> <dbl> <dbl> <dbl>
## 1 Albedo 90 5 Geo Sword Geo DMG 13226 251 876
## 2 Aloy 90 5 Cryo Bow Cryo DMG 10899 234 676
## 3 Amber 90 4 Pyro Bow ATK 9461 223 601
## 4 Ayaka 90 5 Cryo Sword CRIT DMG 12858 342 784
## 5 Ayato 90 5 Hydro Sword CRIT DMG 13715 299 769
## 6 Barbara 90 4 Hydro Catalyst HP 9787 159 669
## 7 Beidou 90 4 Electro Claymore Electro DMG 13050 225 648
## 8 Bennett 90 4 Pyro Sword Energy Rec… 12397 191 771
## 9 Childe 90 5 Hydro Bow Hydro DMG 13103 301 815
## 10 Chongyun 90 4 Cryo Claymore ATK 10984 223 648
## # … with 42 more rows, and 3 more variables: gender <chr>, nation <chr>,
## # birthday <chr>
ggplot(data = genshin_dataset, mapping = aes(x = base_def, y = base_hp, color = nation)) +
geom_point(size = 3, alpha = 0.7) +
scale_color_manual(values = c("Mondstadt" = "aquamarine1",
"Liyue" = "darkorange3",
"Inazuma" = "purple",
"Sumeru" = "chartreuse2",
"Other" = "black"),
name = "Nation") +
theme_bw() +
geom_text(aes(label = character), hjust = 0, vjust = -0.7, size = 3) +
labs(title = "Best defensive character in Teyvat",
x = "Defense",
y = "HP") +
coord_cartesian(xlim = c(500,1000), ylim = c(8500,16000))
Looking at the characters that have highest HP and DEF, we could see that Liyue is quite outstanding (3/5 highest HP, 2/4 highest DEF), with Hutao from Liyue who appears in both category. Hutao has the highest base HP, while Itto has the highest base DEF, which are understandable since Hutao scales on HP and Itto scales on DEF and both are strong DPS 5-star characters. We would confirm this later in this part by looking closely at the average stats by nation.
Learned: Using geom_point(), creating texts next to each point by modifying geom_text, using scale_color_manual to manually change colors by nation, rescaling the visualization using coord_cartesian
We would only look at ATK for this visualization, but I will keep base_def as x-axis for clear character distribution
ggplot(data = genshin_dataset, mapping = aes(x = base_def, y = base_atk, color = nation)) +
geom_point(size = 3, alpha = 0.7) +
scale_color_manual(values = c("Mondstadt" = "aquamarine1",
"Liyue" = "darkorange3",
"Inazuma" = "purple",
"Sumeru" = "chartreuse2",
"Other" = "black"),
name = "Nation") +
theme_bw() +
geom_text(aes(label = character), hjust = 0, vjust = -0.7, size = 3) +
labs(title = "Best offensive character in Teyvat",
x = "Defense",
y = "ATK") +
coord_cartesian(xlim = c(500,1000), ylim = c(100,360))
Inazuma region seems to have lots of highest-in-attack characters (3/5 characters). However, Xiao from Liyue is significantly stronger than all other characters, which once again confirms the domination of Liyue region in ATK. We would look at the average in ATK in the next part to confirm this.
require(gridExtra)
## Loading required package: gridExtra
##
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
##
## combine
hp_plot <- ggplot(data = genshin_dataset, mapping = aes(x = nation, y = base_hp, fill = nation)) +
geom_bar(color = "white", stat = "summary", fun = "mean") +
scale_fill_manual(values = c("Mondstadt" = "aquamarine1",
"Liyue" = "darkorange3",
"Inazuma" = "purple",
"Sumeru" = "chartreuse2",
"Other" = "white"),
name = "Nation") +
stat_summary(aes(label=round(..y.., digits = 1)), fun = mean, geom = "text", size = 3, vjust=-0.1) +
labs(title = "Average HP by Nation",
x = "Nation",
y = "HP") +
coord_cartesian(ylim = c(0,15000))
def_plot <- ggplot(data = genshin_dataset, mapping = aes(x = nation, y = base_def, fill = nation)) +
geom_bar(color = "white", stat = "summary", fun = "mean") +
scale_fill_manual(values = c("Mondstadt" = "aquamarine1",
"Liyue" = "darkorange3",
"Inazuma" = "purple",
"Sumeru" = "chartreuse2",
"Other" = "white"),
name = "Nation") +
stat_summary(aes(label=round(..y.., digits = 1)), fun = mean, geom = "text", size = 3, vjust=-0.1) +
labs(title = "Average DEF by Nation",
x = "Nation",
y = "DEF") +
coord_cartesian(ylim = c(0,800))
atk_plot <- ggplot(data = genshin_dataset, mapping = aes(x = nation, y = base_atk, fill = nation)) +
geom_bar(color = "white", stat = "summary", fun = "mean") +
scale_fill_manual(values = c("Mondstadt" = "aquamarine1",
"Liyue" = "darkorange3",
"Inazuma" = "purple",
"Sumeru" = "chartreuse2",
"Other" = "white"),
name = "Nation") +
stat_summary(aes(label=round(..y.., digits = 1)), fun = mean, geom = "text", size = 3, vjust=-0.1) +
labs(title = "Average ATK by Nation",
x = "Nation",
y = "ATK") +
coord_cartesian(ylim = c(0,300))
grid.arrange(hp_plot, def_plot, atk_plot, nrow=3)
Since Sumeru region has just been introduced with only 2 characters, we are not going to compare it with other nations at this time. 1 character from another world (in Other bar) is also not counted into this analysis.
Looking at the charts, we could see that Liyue obviously has the highest average defensive stats out of all (HP and DEF), followed by Inazuma and Mondstadt respectively. Meanwhile, Inazuma has the highest average offensive stats out of all (ATK), followed by Liyue and Mondstadt respectively. This confirms all earlier analyses on the top defensive and offensive characters.
Another point to take from this analysis is that Mondstadt, which was the first nation introduced into the game, has fallen behind from newer regions. We might expect that later regions will bring more and more powerful characters to the game.
Learned: Use grid_arrange in gridExtra package to stack 3 graphs together, store each graph in a temp variable, calculate the average value of each attribute, display the mean value using stat_summary, practice resizing each graph using coord_cartesian
In this part, we are going to do similar analyses as the previous part. We are going to find out the most offensive and defensive characters, but by vision instead of by nation.
ggplot(data = genshin_dataset, mapping = aes(x = base_def, y = base_hp, color = element)) +
geom_point(size = 3, alpha = 0.7) +
scale_color_manual(values = c("Anemo" = "aquamarine1",
"Cryo" = "cyan2",
"Dendro" = "chartreuse2",
"Pyro" = "red",
"Geo" = "darkorange3",
"Electro" = "purple",
"Hydro" = "blue"
),
name = "Vision") +
theme_bw() +
geom_text(aes(label = character), hjust = 0, vjust = -0.7, size = 3) +
labs(title = "Best defensive character in Teyvat",
x = "Defense",
y = "HP") +
coord_cartesian(xlim = c(500,1000), ylim = c(8500,16000))
There are no outstanding vision with highest HP, but Geo seems to have higher defense stats out of all (2/4 chacracters). This makes sense since lots of Geo characters scale based on DEF and they are more tanky compared to other visions.
ggplot(data = genshin_dataset, mapping = aes(x = base_def, y = base_atk, color = element)) +
geom_point(size = 3, alpha = 0.7) +
scale_color_manual(values = c("Anemo" = "aquamarine1",
"Cryo" = "cyan2",
"Dendro" = "chartreuse2",
"Pyro" = "red",
"Geo" = "darkorange3",
"Electro" = "purple",
"Hydro" = "blue"),
name = "Vision") +
theme_bw() +
geom_text(aes(label = character), hjust = 0, vjust = -0.7, size = 3) +
labs(title = "Best offensive character in Teyvat",
x = "Defense",
y = "ATK") +
coord_cartesian(xlim = c(500,1000), ylim = c(100,360))
Just by looking at the top offensive characters, it’s very difficult to tell which vision has the highest base attack. Anemo has the top character, but following it was 2 Cryo characters. Thus, we would have to confirm that in the following analysis of the average stats by vision.
This analysis is quite repetitive, if I had a chance to redo it, I might make it more concise and by combining the graphs
hp_plot_2 <- ggplot(data = genshin_dataset, mapping = aes(x = element, y = base_hp, fill = element)) +
geom_bar(color = "white", stat = "summary", fun = "mean") +
scale_fill_manual(values = c("Anemo" = "aquamarine1",
"Cryo" = "cyan2",
"Dendro" = "chartreuse2",
"Pyro" = "red",
"Geo" = "darkorange3",
"Electro" = "purple",
"Hydro" = "blue"),
name = "Vision") +
stat_summary(aes(label=round(..y.., digits = 1)), fun = mean, geom = "text", size = 3, vjust=-0.1) +
labs(title = "Average HP by Vision",
x = "Vision",
y = "HP") +
coord_cartesian(ylim = c(0,15000))
def_plot_2 <- ggplot(data = genshin_dataset, mapping = aes(x = element, y = base_def, fill = element)) +
geom_bar(color = "white", stat = "summary", fun = "mean") +
scale_fill_manual(values = c("Anemo" = "aquamarine1",
"Cryo" = "cyan2",
"Dendro" = "chartreuse2",
"Pyro" = "red",
"Geo" = "darkorange3",
"Electro" = "purple",
"Hydro" = "blue"),
name = "Vision") +
stat_summary(aes(label=round(..y.., digits = 1)), fun = mean, geom = "text", size = 3, vjust=-0.1) +
labs(title = "Average DEF by Vision",
x = "Vision",
y = "DEF") +
coord_cartesian(ylim = c(0,850))
atk_plot_2 <- ggplot(data = genshin_dataset, mapping = aes(x = element, y = base_atk, fill = element)) +
geom_bar(color = "white", stat = "summary", fun = "mean") +
scale_fill_manual(values = c("Anemo" = "aquamarine1",
"Cryo" = "cyan2",
"Dendro" = "chartreuse2",
"Pyro" = "red",
"Geo" = "darkorange3",
"Electro" = "purple",
"Hydro" = "blue"),
name = "Vision") +
stat_summary(aes(label=round(..y.., digits = 1)), fun = mean, geom = "text", size = 3, vjust=-0.1) +
labs(title = "Average ATK by Vision",
x = "Vision",
y = "ATK") +
coord_cartesian(ylim = c(0,300))
grid.arrange(hp_plot_2, def_plot_2, atk_plot_2, nrow=3)
Similar to the analysis above of characters by nation, since the Dendro element has just been added into the game, we would not look at its stats since it might not be the representative of the whole element.
Hydro vision has slightly higher base HP than others, yet it’s not too significant. Nevertheless, when it comes to base DEF, Geo surpasses other visions by quite a big amount. This was reflected in the previous analysis, with 2 Geo chacracters in the top 4 highest base defense. On the other hand, talking about base ATK, even though an Anemo character has the highest base ATK, the average base ATK of Anemo falls behind Cryo and Electro. Thus, suprisingly, this makes Cryo the highest average base_ATK vision.
To sum up this analysis, each vision seems to have their own strengths and weaknesses. While Hydro and Geo have characters that are more on the defensive side, Cryo and Electro have more characters that are more on the offensive side, and vice versa.
After delving into the world of Teyvat, we were able to understand more about the characters, their vision, and the nations.
Even though newer nations seem to get stronger and more impressive characters to keep players excited as the game progresses, different vision has its own strength. Inazuma and Liyue are some of the nations introduced later into the game, and proves to have significantly stronger characters than Mondstadt rosters, which was introduced when the game was first launched. Yet, for different visions, while Geo and Hydro have slightly higher overall defensive performance, Cryo and Electro have slightly higher overall offensive performance. This shows Hoyoverse’s effort in balancing different visions with different roles they could fill.
In addition, we also took a brief look into how well Hoyoverse has been doing in terms of banner revenue and found that they are making more and more money with the introduction of new regions and versions. Hopefully, this would hold true as the game progresses through different stages in the future.
With regular updates, original events, engaging storyline, beautiful characters and open world, Hoyoverse as a company and Genshin Impact in particular are doing pretty well in setting the new standard for the RPG market. Though they have just started their journey and got tremendous support from an early stage, fans could expect to experience much greater contents from the company in the future.