import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# ----------------------------
# Team xG Data
# ----------------------------
teams = [
"Spain", "Portugal", "Morocco", "Canada", "France", "Paraguay",
"Brazil", "Norway", "Mexico", "England", "Argentina", "Egypt",
"Switzerland", "Colombia", "Belgium", "USA", "Germany", "Netherlands"
]
xg_conceded = [
0.30, 1.17, 1.29, 0.65, 1.04, 1.43,
0.80, 1.52, 0.78, 1.17, 0.78, 1.65,
1.05, 0.62, 1.35, 1.24, 0.81, 0.90
]
xg_created = [
1.95, 1.40, 1.41, 1.94, 2.19, 0.32,
2.46, 1.68, 1.33, 1.79, 1.82, 1.20,
1.61, 1.48, 1.82, 1.23, 2.08, 1.37
]
# ----------------------------
# Create DataFrame
# ----------------------------
df = pd.DataFrame({
"Team": teams,
"xG Created": xg_created,
"xG Conceded": xg_conceded
})
df["xG Difference"] = df["xG Created"] - df["xG Conceded"]
df["Attack/Defense Ratio"] = df["xG Created"] / df["xG Conceded"]
print("\nComplete Data")
print(df)
# ----------------------------
# Scatter Plot (Attack vs Defence)
# ----------------------------
plt.figure(figsize=(10, 8))
plt.scatter(df["xG Conceded"], df["xG Created"], s=90)
for _, row in df.iterrows():
plt.text(row["xG Conceded"] + 0.02,
row["xG Created"] + 0.02,
row["Team"],
fontsize=8)
plt.axvline(df["xG Conceded"].mean(),
linestyle="--",
linewidth=1,
label="Average Defence")
plt.axhline(df["xG Created"].mean(),
linestyle="--",
linewidth=1,
label="Average Attack")
plt.xlabel("xG Conceded per Match (Lower is Better)")
plt.ylabel("xG Created per Match (Higher is Better)")
plt.title("2026 FIFA World Cup: Attack vs Defence")
plt.grid(True, alpha=0.3)
plt.legend()
plt.tight_layout()
plt.show()
# ----------------------------
# xG Difference Ranking
# ----------------------------
ranking = df.sort_values("xG Difference", ascending=True)
plt.figure(figsize=(9, 8))
bars = plt.barh(ranking["Team"], ranking["xG Difference"])
for bar in bars:
width = bar.get_width()
plt.text(width + 0.02,
bar.get_y() + bar.get_height()/2,
f"{width:.2f}",
va='center')
plt.xlabel("xG Difference")
plt.title("Net xG Difference per Match")
plt.grid(axis='x', linestyle='--', alpha=0.3)
plt.tight_layout()
plt.show()
# ----------------------------
# Attack vs Defence Comparison
# ----------------------------
plt.figure(figsize=(14, 7))
x = np.arange(len(df))
width = 0.38
plt.bar(x - width/2,
df["xG Created"],
width,
label="xG Created")
plt.bar(x + width/2,
df["xG Conceded"],
width,
label="xG Conceded")
# Add values above bars
for i in range(len(df)):
plt.text(i - width/2,
df["xG Created"][i] + 0.03,
f'{df["xG Created"][i]:.2f}',
ha='center',
fontsize=8)
plt.text(i + width/2,
df["xG Conceded"][i] + 0.03,
f'{df["xG Conceded"][i]:.2f}',
ha='center',
fontsize=8)
plt.xticks(x, df["Team"], rotation=45, ha='right')
plt.ylabel("xG per Match")
plt.title("Attack vs Defence Comparison")
plt.legend()
plt.grid(axis='y', linestyle='--', alpha=0.3)
plt.tight_layout()
plt.show()
# ----------------------------
# Top 5 Attack
# ----------------------------
print("\nTop 5 Attacking Teams")
print(df.nlargest(5, "xG Created")[["Team", "xG Created"]])
# ----------------------------
# Top 5 Defence
# ----------------------------
print("\nTop 5 Defensive Teams")
print(df.nsmallest(5, "xG Conceded")[["Team", "xG Conceded"]])
# ----------------------------
# Best Overall xG Difference
# ----------------------------
print("\nTop Teams by xG Difference")
print(df.sort_values("xG Difference", ascending=False)[
["Team", "xG Created", "xG Conceded", "xG Difference"]
])
To embed this project on your website, copy the following code and paste it into your website's HTML: