import matplotlib.pyplot as plt

# ===========================================
# 2026 FIFA World Cup
# Attack vs Defence (Expected Goals)
# X-axis : xG Conceded per Match (lower = better defence)
# Y-axis : xG Created per Match (higher = better attack)
# ===========================================

teams = [
    "Spain", "Portugal", "Morocco", "Canada", "France",
    "Paraguay", "Brazil", "Norway", "Mexico", "England",
    "Argentina", "Egypt", "Switzerland", "Colombia",
    "Belgium", "USA", "GER", "NED"
]

# xG conceded (X-axis)
x = [
    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 (Y-axis)
y = [
    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
]

plt.style.use("default")

fig, ax = plt.subplots(figsize=(10, 8), dpi=150)

fig.patch.set_facecolor("white")
ax.set_facecolor("white")

# Highlight semifinalists
colors = {
    "Spain": "#D4AF37",      # Gold
    "Argentina": "#C0C0C0",  # Silver
    "England": "#CD7F32",    # Bronze
    "France": "#C62828"      # Red
}

# Plot teams
for team, x_val, y_val in zip(teams, x, y):

    color = colors.get(team, "#1F4E79")
    size = 170 if team in colors else 90

    ax.scatter(
        x_val,
        y_val,
        s=size,
        color=color,
        edgecolor="white",
        linewidth=1.4,
        zorder=3
    )

    # Team name
    ax.text(
        x_val + 0.02,
        y_val + 0.02,
        team,
        fontsize=9,
        weight="bold" if team in colors else "normal"
    )

    # Coordinates
    ax.text(
        x_val + 0.02,
        y_val - 0.05,
        f"({x_val:.2f}, {y_val:.2f})",
        fontsize=7,
        color="gray"
    )

# Tournament averages
avg_x = sum(x) / len(x)
avg_y = sum(y) / len(y)

ax.axvline(avg_x, color="gray", linestyle="--", linewidth=1.2)
ax.axhline(avg_y, color="gray", linestyle="--", linewidth=1.2)

# Quadrant labels
ax.text(
    0.22, 2.62,
    "Elite Defence\nElite Attack",
    fontsize=11,
    weight="bold",
    color="#0B6E4F",
    ha="left",
    va="top"
)

ax.text(
    1.78, 2.62,
    "Weak Defence\nElite Attack",
    fontsize=11,
    color="#E67E22",
    ha="right",
    va="top"
)

ax.text(
    0.22, 0.25,
    "Elite Defence\nWeak Attack",
    fontsize=11,
    color="#1565C0",
    ha="left",
    va="bottom"
)

ax.text(
    1.78, 0.25,
    "Weak Defence\nWeak Attack",
    fontsize=11,
    color="#C0392B",
    ha="right",
    va="bottom"
)

# Axes
ax.set_xlim(0.2, 1.8)
ax.set_ylim(0.2, 2.7)

# Optional: Uncomment to place the best defensive teams on the right.
# ax.invert_xaxis()

ax.set_xlabel(
    "xG Conceded per Match",
    fontsize=13,
    weight="bold"
)

ax.set_ylabel(
    "xG Created per Match",
    fontsize=13,
    weight="bold"
)

ax.set_title(
    "2026 FIFA World Cup\nAttack vs Defence (Expected Goals per Match)",
    fontsize=17,
    weight="bold",
    pad=15
)

# Grid
ax.grid(True, linestyle="--", linewidth=0.6, alpha=0.35)
ax.set_axisbelow(True)

# Remove unnecessary borders
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)

plt.tight_layout()
plt.show()

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: