import matplotlib.pyplot as plt
import numpy as np

# Match order (Latest to Earliest)
matches = ["Final/\nBronze", "SF", "QF", "R16", "R32", "GS3", "GS2", "GS1"]

data = {
    "Spain": {
        "xGF":[2.29,1.63,1.96,1.69,2.32,0.86,2.30,2.10],
        "xGA":[0.22,0.31,0.34,0.63,0.32,0.20,0.14,0.20],
        "Opp":["ARG","FRA","BEL","POR","AUT","URU","KSA","CPV"]
    },

    "Argentina":{
        "xGF":[0.22,1.59,1.94,2.84,2.26,2.13,2.36,1.26],
        "xGA":[2.29,0.53,0.47,0.89,0.47,0.76,0.53,0.32],
        "Opp":["ESP","ENG","SUI","EGY","CPV","JOR","AUT","ALG"]
    },

    "England":{
        "xGF":[2.88,0.53,1.04,1.61,2.16,1.56,1.36,3.20],
        "xGA":[2.88,1.59,0.68,1.88,0.77,0.66,0.17,0.70],
        "Opp":["FRA","ARG","NOR","MEX","COD","PAN","GHA","CRO"]
    },

    "France":{
        "xGF":[2.88,0.31,3.69,1.45,3.24,1.50,2.67,1.79],
        "xGA":[2.88,1.63,0.14,0.13,0.70,1.70,0.63,0.53],
        "Opp":["ENG","ESP","MAR","PAR","SWE","NOR","IRQ","SEN"]
    }
}

fig, axes = plt.subplots(2,2,figsize=(15,10),sharex=True,sharey=True)

axes = axes.flatten()

bar_width = 0.38
x = np.arange(len(matches))

for ax, (team, values) in zip(axes, data.items()):

    bars1 = ax.bar(x-bar_width/2,
                   values["xGF"],
                   width=bar_width,
                   color="royalblue",
                   label="xGF")

    bars2 = ax.bar(x+bar_width/2,
                   values["xGA"],
                   width=bar_width,
                   color="crimson",
                   label="xGA")

    # Annotate bars
    for i, (b1, b2, opp) in enumerate(zip(bars1, bars2, values["Opp"])):

        # xGF value
        ax.text(b1.get_x()+b1.get_width()/2,
                b1.get_height()+0.05,
                f"{values['xGF'][i]:.2f}",
                ha='center',
                fontsize=8,
                color='royalblue',
                fontweight='bold')

        # Opponent
        ax.text(b2.get_x()+b2.get_width()/2,
                b2.get_height()+0.25,
                opp,
                ha='center',
                fontsize=8,
                fontweight='bold')

        # xGA value
        ax.text(b2.get_x()+b2.get_width()/2,
                b2.get_height()+0.05,
                f"{values['xGA'][i]:.2f}",
                ha='center',
                fontsize=8,
                color='crimson',
                fontweight='bold')

    ax.set_title(team,fontsize=15,fontweight='bold')
    ax.set_xticks(x)
    ax.set_xticklabels(matches)
    ax.set_ylim(0,4)
    ax.grid(axis='y',linestyle='--',alpha=0.35)
    ax.legend(frameon=False)

fig.suptitle("2026 FIFA World Cup Semi-finalists\nExpected Goals For (xGF) vs Expected Goals Against (xGA)",
             fontsize=19,
             fontweight='bold')

fig.supxlabel("Tournament Stage",fontsize=13,fontweight='bold')
fig.supylabel("Expected Goals (xG)",fontsize=13,fontweight='bold')

plt.tight_layout(rect=[0,0,1,0.95])
plt.show()

Embed on website

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