IIHF World Championship Analysis
Beginner
10 min read
16 views
Nov 27, 2025
Python Code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
# Load World Championship data
wc_df = pd.read_csv("data/world_championship.csv")
# Tournament statistics by country
country_stats = wc_df.groupby("country").agg({
"goals_for": "mean",
"goals_against": "mean",
"shots_for": "mean",
"shots_against": "mean",
"powerplay_goals": "sum",
"wins": "sum"
}).round(2)
country_stats["goal_differential"] = country_stats["goals_for"] - country_stats["goals_against"]
country_stats = country_stats.sort_values("goal_differential", ascending=False)
print("World Championship Country Statistics:")
print(country_stats)
# Visualization
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# Goals for vs against
axes[0,0].scatter(country_stats["goals_for"], country_stats["goals_against"],
s=country_stats["wins"]*50, alpha=0.6)
axes[0,0].plot([0, country_stats["goals_for"].max()],
[0, country_stats["goals_for"].max()],
"r--", alpha=0.5)
axes[0,0].set_title("Goals For vs Goals Against")
axes[0,0].set_xlabel("Goals For")
axes[0,0].set_ylabel("Goals Against")
axes[0,0].grid(True, alpha=0.3)
# Top countries by goal differential
top_countries = country_stats.nlargest(10, "goal_differential")
top_countries["goal_differential"].plot(kind="barh", ax=axes[0,1], color="green")
axes[0,1].set_title("Top 10 Countries by Goal Differential")
axes[0,1].set_xlabel("Goal Differential")
axes[0,1].set_ylabel("Country")
# Shooting efficiency
country_stats["shooting_pct"] = (country_stats["goals_for"] / country_stats["shots_for"]) * 100
country_stats["shooting_pct"].nlargest(12).plot(kind="bar", ax=axes[1,0], color="steelblue")
axes[1,0].set_title("Top 12 Shooting Percentage")
axes[1,0].set_xlabel("Country")
axes[1,0].set_ylabel("Shooting %")
axes[1,0].tick_params(axis="x", rotation=45)
# Powerplay effectiveness
country_stats.nlargest(12, "powerplay_goals")["powerplay_goals"].plot(
kind="bar", ax=axes[1,1], color="orange")
axes[1,1].set_title("Top Powerplay Teams")
axes[1,1].set_xlabel("Country")
axes[1,1].set_ylabel("Powerplay Goals")
axes[1,1].tick_params(axis="x", rotation=45)
plt.tight_layout()
plt.savefig("outputs/world_championship_analysis.png", dpi=300, bbox_inches="tight")
plt.show()
# Medal prediction model
wc_df["expected_points"] = (
wc_df["goals_for"] * 0.4 +
wc_df["shots_for"] * 0.02 -
wc_df["goals_against"] * 0.3
)
medal_contenders = wc_df.nlargest(8, "expected_points")[
["country", "goals_for", "goals_against", "expected_points"]
]
print("\nMedal Contenders:")
print(medal_contenders)R Code
library(tidyverse)
library(ggplot2)
library(gridExtra)
# Load World Championship data
wc_df <- read.csv("data/world_championship.csv")
# Country statistics
country_stats <- wc_df %>%
group_by(country) %>%
summarise(
goals_for = mean(goals_for, na.rm = TRUE),
goals_against = mean(goals_against, na.rm = TRUE),
shots_for = mean(shots_for, na.rm = TRUE),
shots_against = mean(shots_against, na.rm = TRUE),
powerplay_goals = sum(powerplay_goals, na.rm = TRUE),
wins = sum(wins, na.rm = TRUE)
) %>%
mutate(goal_differential = goals_for - goals_against) %>%
arrange(desc(goal_differential))
print("World Championship Country Statistics:")
print(country_stats)
# Visualization
p1 <- ggplot(country_stats, aes(x = goals_for, y = goals_against, size = wins)) +
geom_point(alpha = 0.6, color = "steelblue") +
geom_abline(slope = 1, intercept = 0, linetype = "dashed", color = "red", alpha = 0.5) +
theme_minimal() +
labs(title = "Goals For vs Goals Against", x = "Goals For", y = "Goals Against")
p2 <- country_stats %>%
top_n(10, goal_differential) %>%
ggplot(aes(x = reorder(country, goal_differential), y = goal_differential)) +
geom_bar(stat = "identity", fill = "green") +
coord_flip() +
theme_minimal() +
labs(title = "Top 10 Countries by Goal Differential", x = "Country", y = "Goal Differential")
# Shooting efficiency
country_stats <- country_stats %>%
mutate(shooting_pct = (goals_for / shots_for) * 100)
p3 <- country_stats %>%
top_n(12, shooting_pct) %>%
ggplot(aes(x = reorder(country, shooting_pct), y = shooting_pct)) +
geom_bar(stat = "identity", fill = "steelblue") +
theme_minimal() +
labs(title = "Top 12 Shooting Percentage", x = "Country", y = "Shooting %") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
p4 <- country_stats %>%
top_n(12, powerplay_goals) %>%
ggplot(aes(x = reorder(country, powerplay_goals), y = powerplay_goals)) +
geom_bar(stat = "identity", fill = "orange") +
theme_minimal() +
labs(title = "Top Powerplay Teams", x = "Country", y = "Powerplay Goals") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
# Combine plots
combined_plot <- grid.arrange(p1, p2, p3, p4, ncol = 2)
ggsave("outputs/world_championship_analysis_r.png", combined_plot, width = 14, height = 10, dpi = 300)
# Medal prediction
wc_df <- wc_df %>%
mutate(expected_points = goals_for * 0.4 + shots_for * 0.02 - goals_against * 0.3)
medal_contenders <- wc_df %>%
arrange(desc(expected_points)) %>%
select(country, goals_for, goals_against, expected_points) %>%
head(8)
print("Medal Contenders:")
print(medal_contenders)Discussion
Have questions or feedback? Join our community discussion on
Discord or
GitHub Discussions.
Table of Contents
Related Topics
Quick Actions