Analysis on the Pros of Overwatch
In a lot of esports, players watch the professional players as they have both a high mechanical skill and a deep understanding of the game.
import pandas as pd
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:100% !important; }</style>"))
df = pd.read_csv("owl.csv")
df
df_correleations = df[["eliminations_avg_per_10m","deaths_avg_per_10m","hero_damage_avg_per_10m","healing_avg_per_10m","ultimates_earned_avg_per_10m","final_blows_avg_per_10m","time_played_total"]]
df_corr_table = df_correleations.corr()
df_corr_table
This is great, but let's filter out correlations below .5 because they aren't strong
df_corr_table[(df_corr_table> .5) | (df_corr_table <-.5) & (df_corr_table < 1.0)]
this looks great, but we are going to make this cleaner with the .drop() function so that the table doesn't have so many NaNs
df_column_drop = df_corr_table.drop(["deaths_avg_per_10m", "ultimates_earned_avg_per_10m", "time_played_total"])
df_relevant_correlations = df_column_drop.drop(["deaths_avg_per_10m", "ultimates_earned_avg_per_10m", "time_played_total"],axis=1)
df_relevant_correlations
it appears that
Eliminations and Hero Damage have a strong positive correlation with each other
Eliminations and Final blows have a strong positive correlation with each other
Eliminations and Healing have a moderate negative correlation with each other
Final blows and Hero damage have a strong positive correlation with each other
Final blows and Healing have a moderate negative correlation with each other
df_elims = df[["role", "name", "team", "eliminations_avg_per_10m"]]
df_elims.nlargest(10, "eliminations_avg_per_10m")
df_damage = df[["role", "name", "team", "hero_damage_avg_per_10m"]]
df_damage.nlargest(10, "hero_damage_avg_per_10m")
df_final_blows = df[["role", "name", "team", "final_blows_avg_per_10m"]]
df_final_blows.nlargest(10, "final_blows_avg_per_10m")
df_ultimates = df[["role", "name", "team", "ultimates_earned_avg_per_10m"]]
df_ultimates.nlargest(10, "ultimates_earned_avg_per_10m")
df_heals = df[["role", "name", "team", "healing_avg_per_10m"]]
df_heals.nlargest(10, "healing_avg_per_10m")
df_deaths = df[["role", "name", "team", "deaths_avg_per_10m"]]
df_deaths.nsmallest(10, "deaths_avg_per_10m")
It wouldn't be fair to judge the stats for pro's who don't get a lot of play time.
let's see which pros got the most play time
df_time_largest = df[["role", "name", "team", "time_played_total"]]
df_time_largest.nlargest(10, "time_played_total")
df_time_smallest = df[["role", "name", "team", "time_played_total"]]
df_time_smallest.nsmallest(10, "time_played_total")
Explanation For What I have chosen
I have choosen Eliminations, Damage, and Deaths for this project because I wanted to apply the findings to my own games.
Although these statistics do not reflect the skill level of a player, I personally would like to use these to figure out how I personally compare in my own competitive games to the pros.
df_group_role = df.groupby("role")
df_group_role = df_group_role.agg("sum").reset_index()
df_group_role
df_group_role.plot.bar(x = "role")
df_group_role[["role","count"]]
df_group_role.plot.bar(x = "role", y = "count" )
across all the roles, the count seems to be pretty spread evenly
df_group_role["Overall Average Eliminations Per 10m"] = df_group_role["eliminations_avg_per_10m"]/df_group_role["count"]
df_group_role_elimminations = df_group_role[["role","Overall Average Eliminations Per 10m"]]
df_group_role_elimminations.nlargest(3, "Overall Average Eliminations Per 10m")
df_group_role.plot.bar(x = "role", y = "Overall Average Eliminations Per 10m" )
it appears that The tanks and DPS get almost about the same amount of damage. The Tanks might have more than the supports because they get more opportunities to do damage and finish off targets.
It is also possible that during the GOATs meta (3 tanks 3 supports) tanks were the primary damage dealers.
df_group_role["Overall Average Damage Dealt per 10m"] = df_group_role["hero_damage_avg_per_10m"]/df_group_role["count"]
df_group_role_Damage = df_group_role[["role","Overall Average Damage Dealt per 10m"]]
df_group_role_Damage.nlargest(3, "Overall Average Damage Dealt per 10m")
df_group_role.plot.bar(x = "role", y = "Overall Average Damage Dealt per 10m" )
In this category, the DPS did 1000 more damage per 10 min compared to the tanks.
It is possible that the dps can focus more on dealing damage thus they would have more than the tanks. If we compare this back to the eliminations, it would appear that the DPS do the majority of the damage, and the tanks would finish off low health oppponents
df_group_role["Overall Average Deaths Per 10m"] = df_group_role["deaths_avg_per_10m"]/df_group_role["count"]
df_group_role_Deaths = df_group_role[["role","Overall Average Deaths Per 10m"]]
df_group_role_Deaths.nlargest(3,"Overall Average Deaths Per 10m")
df_group_role.plot.bar(x = "role", y = "Overall Average Deaths Per 10m" )
In terms of deaths, it appears that the dps and tanks die more than the supports.
The values are reasonable as supports in this game have better abilities that help them self sustain(Lucio amp and wall riding, Brigitte having a shield and inspire, Ana having sleep and nade, Moria healing orb and fade out etc.
DPS and tanks constantly need to put themselves in risky positions to get value and their abilities for the most part don't heal or sustain themselves (with obvious exceptions like soldier health pad, doomfist shields, and tracer recall).
df_group_team = df.groupby("team")
df_group_team = df_group_team.agg("sum").reset_index()
df_group_team
df_group_team[["team","count"]]
df_group_team.plot.bar(x = "team", y = "count" )
q1 = df_group_team["count"].quantile(.25)
q3 = df_group_team["count"].quantile(.75)
iqr = q3 - q1
lower_bound = q1 -(1.5 * iqr)
upper_bound = q3 +(1.5 * iqr)
print({"Quartile 1": q1})
print({"Quartile 3":q3})
print({"IQR": iqr })
print({"Lower Bound" : lower_bound})
print({"Upper Bound" : upper_bound})
Although our teams don't have any outliers by the IQR, we probably should exclude the the Boston Uprising, LA Valliant, and Washington Justice as they don't have enough for a team
df_group_team["Overall Average Eliminations Per 10m"] = df_group_team["eliminations_avg_per_10m"]/df_group_team["count"]
df_team_largest_elim = df_group_team[["team","Overall Average Eliminations Per 10m"]]
df_team_largest_elim.nlargest(20,"Overall Average Eliminations Per 10m")
df_group_team.plot.bar(x = "team", y = "Overall Average Eliminations Per 10m" )
This looks pretty messy, let's calculate for any outliers
q1 = df_group_team["Overall Average Eliminations Per 10m"].quantile(.25)
q3 = df_group_team["Overall Average Eliminations Per 10m"].quantile(.75)
iqr = q3 - q1
lower_bound = q1 -(1.5 * iqr)
upper_bound = q3 +(1.5 * iqr)
print({"Quartile 1": q1})
print({"Quartile 3":q3})
print({"IQR": iqr })
print({"Lower Bound" : lower_bound})
print({"Upper Bound" : upper_bound})
df_group_team["Overall Average Damage Dealt per 10m"] = df_group_team["hero_damage_avg_per_10m"]/df_group_team["count"]
df_team_largest_damage = df_group_team[["team","Overall Average Damage Dealt per 10m"]]
df_team_largest_damage.nlargest(20,"Overall Average Damage Dealt per 10m")
df_team_largest_damage.plot.bar(x = "team", y = "Overall Average Damage Dealt per 10m" )
Surpisingly enough, Boston seems to have a higher damage dealt dispite having less players. This is odd because it wasn't an issue for eliminations.
df_group_team["Overall Average Deaths Per 10m"] = df_group_team["deaths_avg_per_10m"]/df_group_team["count"]
df_team_smallest_death = df_group_team[["team","Overall Average Deaths Per 10m"]]
df_team_smallest_death.nsmallest(20,"Overall Average Deaths Per 10m")
df_team_smallest_death.plot.bar(x = "team", y = "Overall Average Deaths Per 10m" )
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model = model.fit(df[["eliminations_avg_per_10m","deaths_avg_per_10m","hero_damage_avg_per_10m", "healing_avg_per_10m"]], df["ultimates_earned_avg_per_10m"])