import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from scipy.interpolate import make_interp_spline
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
# Set seaborn style and black background
sns.set_style("darkgrid")
plt.style.use("dark_background")
# Load data
df = pd.read_csv('big6_transfers.csv')
df['year'] = df['year'].astype(int)
# Compute cumulative spend per club-year
df.sort_values(['club', 'year'], inplace=True)
df['cumulative'] = df.groupby('club')['net_spend_million_eur'].cumsum()
# List of clubs, logos and colours
clubs = [
("Manchester United", "logos/manutd.png"),
("Arsenal", "logos/arsenal.png"),
("Tottenham Hotspur", "logos/tottenham.png"),
("Liverpool", "logos/liverpool.png"),
("Chelsea", "logos/chelsea.png"),
("Manchester City", "logos/mancity.png")
]
club_colors = {
"Arsenal": "#db0007",
"Chelsea": "#0000dd",
"Manchester City": "#6caddf",
"Manchester United": "#ffe500",
"Liverpool": "#009782",
"Tottenham Hotspur": "#F4F8FC"
}
fig, ax = plt.subplots(figsize=(14, 7))
fig.patch.set_facecolor('#1e1e1e')
ax.set_facecolor('#1e1e1e')
for club_name, logo_path in clubs:
# Get and prepare data
club_data = df[df['club'] == club_name].sort_values('year')
club_data['cumulative'] = club_data['net_spend_million_eur'].cumsum()
x = club_data['year'].values
y = club_data['cumulative'].values
# Smooth line with spline
x_new = np.linspace(x.min(), x.max(), 300)
spl = make_interp_spline(x, y, k=3)
y_smooth = spl(x_new)
# Plot line
ax.plot(x_new, y_smooth, linewidth=3, color=club_colors[club_name])
# Add logo with slight x offset
img = plt.imread(logo_path)
imagebox = OffsetImage(img, zoom=0.08)
offset_x = (x_new[-1] - x_new[0]) * \
(0.01 if club_name != "Chelsea" else 0.04) # Avoid overlapping
ab = AnnotationBbox(imagebox,
(x_new[-1] + offset_x, y_smooth[-1]),
frameon=False,
box_alignment=(0.0, 0.5))
ax.add_artist(ab)
# Add gold dots for title wins
wins = club_data[club_data['win'] == 'yes']
for win_year in wins['year']:
idx = (np.abs(x_new - win_year)).argmin()
ax.scatter(x_new[idx], y_smooth[idx], color='gold', edgecolor='white',
s=100, zorder=5, linewidth=1.5)
# Labels and formatting
ax.set_ylabel('million €', fontsize=12)
ax.set_title("Cumulative net transfer spend (2016–2025) – 'Big Six' clubs",
fontsize=16, weight='bold')
# Add dummy dot
winner_dot = ax.scatter([], [], color='gold', edgecolor='white', s=100,
linewidth=1.5, label='Premier League Winner')
ax.legend(handles=[winner_dot], loc='upper left', fontsize=12, frameon=False)
# Add source text
ax.text(1.0, -0.05, 'source: Transfermarkt',
transform=ax.transAxes,
ha='right', va='top',
fontsize=9, color='gray', alpha=0.7)
# Remove all axes box
for spine in ax.spines.values():
spine.set_visible(False)
plt.grid(visible=True, alpha=0.3)
plt.tight_layout()
plt.show()