Comparing European Leagues (SHL, Liiga, DEL, NL)

Beginner 10 min read 1 views Nov 27, 2025

Python Code

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# Load European league data
leagues_df = pd.read_csv("data/european_leagues.csv")

# League strength indicators
league_stats = leagues_df.groupby("league").agg({
    "goals_per_game": "mean",
    "shots_per_game": "mean",
    "powerplay_pct": "mean",
    "avg_age": "mean"
}).round(2)

print("League Comparison Statistics:")
print(league_stats)

# Visualization
fig, axes = plt.subplots(2, 2, figsize=(14, 10))

# Goals per game by league
sns.boxplot(data=leagues_df, x="league", y="goals_per_game", ax=axes[0,0])
axes[0,0].set_title("Goals Per Game Distribution by League")
axes[0,0].set_xlabel("League")
axes[0,0].set_ylabel("Goals Per Game")

# Shots per game comparison
sns.violinplot(data=leagues_df, x="league", y="shots_per_game", ax=axes[0,1])
axes[0,1].set_title("Shots Per Game Distribution")
axes[0,1].set_xlabel("League")
axes[0,1].set_ylabel("Shots Per Game")

# Powerplay percentage
league_stats["powerplay_pct"].plot(kind="bar", ax=axes[1,0], color="steelblue")
axes[1,0].set_title("Average Powerplay Percentage by League")
axes[1,0].set_xlabel("League")
axes[1,0].set_ylabel("PP %")
axes[1,0].tick_params(axis="x", rotation=45)

# Average age comparison
league_stats["avg_age"].plot(kind="bar", ax=axes[1,1], color="coral")
axes[1,1].set_title("Average Player Age by League")
axes[1,1].set_xlabel("League")
axes[1,1].set_ylabel("Age")
axes[1,1].tick_params(axis="x", rotation=45)

plt.tight_layout()
plt.savefig("outputs/euro_league_comparison.png", dpi=300, bbox_inches="tight")
plt.show()

# Quality of competition analysis
leagues_df["quality_score"] = (
    leagues_df["goals_per_game"] * 0.3 +
    leagues_df["shots_per_game"] * 0.2 +
    leagues_df["powerplay_pct"] * 0.5
)

quality_ranking = leagues_df.groupby("league")["quality_score"].mean().sort_values(ascending=False)
print("\nLeague Quality Ranking:")
print(quality_ranking)

R Code

library(tidyverse)
library(ggplot2)
library(gridExtra)

# Load European league data
leagues_df <- read.csv("data/european_leagues.csv")

# League statistics summary
league_stats <- leagues_df %>%
  group_by(league) %>%
  summarise(
    avg_goals = mean(goals_per_game, na.rm = TRUE),
    avg_shots = mean(shots_per_game, na.rm = TRUE),
    avg_pp = mean(powerplay_pct, na.rm = TRUE),
    avg_age = mean(avg_age, na.rm = TRUE)
  ) %>%
  arrange(desc(avg_goals))

print("League Comparison Statistics:")
print(league_stats)

# Visualization plots
p1 <- ggplot(leagues_df, aes(x = league, y = goals_per_game, fill = league)) +
  geom_boxplot() +
  theme_minimal() +
  labs(title = "Goals Per Game by League", x = "League", y = "Goals Per Game") +
  theme(legend.position = "none", axis.text.x = element_text(angle = 45, hjust = 1))

p2 <- ggplot(leagues_df, aes(x = league, y = shots_per_game, fill = league)) +
  geom_violin() +
  theme_minimal() +
  labs(title = "Shots Per Game Distribution", x = "League", y = "Shots Per Game") +
  theme(legend.position = "none", axis.text.x = element_text(angle = 45, hjust = 1))

p3 <- ggplot(league_stats, aes(x = reorder(league, -avg_pp), y = avg_pp)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  theme_minimal() +
  labs(title = "Average Powerplay % by League", x = "League", y = "PP %") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

p4 <- ggplot(league_stats, aes(x = reorder(league, -avg_age), y = avg_age)) +
  geom_bar(stat = "identity", fill = "coral") +
  theme_minimal() +
  labs(title = "Average Age by League", x = "League", y = "Age") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Combine plots
combined_plot <- grid.arrange(p1, p2, p3, p4, ncol = 2)

ggsave("outputs/euro_league_comparison_r.png", combined_plot, width = 14, height = 10, dpi = 300)

# Quality score calculation
leagues_df <- leagues_df %>%
  mutate(quality_score = goals_per_game * 0.3 + shots_per_game * 0.2 + powerplay_pct * 0.5)

quality_ranking <- leagues_df %>%
  group_by(league) %>%
  summarise(avg_quality = mean(quality_score, na.rm = TRUE)) %>%
  arrange(desc(avg_quality))

print("League Quality Ranking:")
print(quality_ranking)

Discussion

Have questions or feedback? Join our community discussion on Discord or GitHub Discussions.