Skip to content

The data

Every real-data number on this site comes from one of the sources below. Most pieces end with a "Reproduce the analysis" snippet; this page gets you the files they read.

Results and odds: football-data.co.uk

football-data.co.uk publishes a file for each season of the Scottish Premiership (SC0) and Championship (SC1). This site uses 2000/01 to 2025/26: 26 seasons, 10,471 matches. Each row is one match: the date, the teams, the full-time and half-time scores, and bookmakers' odds (Bet365's from 2002/03). The Premiership files also record shots, shots on target, corners, fouls and cards; the Championship's are mainly results. Their notes explain every column.

The files are football-data.co.uk's, used here with their agreement. This site doesn't host copies: the script below downloads them from football-data.co.uk itself. The season in progress, 2026/27, is left out on purpose, so your numbers match the articles. 54 articles read these files.

Get the files

  1. Make an empty folder and save get_football_data.py in it (or copy it from below).
  2. Run python get_football_data.py there. It fetches all 52 files, about 3 MB, in under a minute, and skips any you already have.
  3. Run any article's snippet in the same folder. The files are named the way the snippets expect, such as SC0_2425.csv.
Show the Python20 lines, ready to copy and run.
# From Football Data Science by Bryan McGuire. Free to use with credit.
# https://www.footballdatascience.co.uk/data
# Downloads the Scottish results and odds files the site's snippets use, straight from football-data.co.uk
# (their files, not this site's). Run it once in an empty folder, then run any article's snippet there.
import os
import time
import urllib.request

SEASONS = [f"{y % 100:02d}{(y + 1) % 100:02d}" for y in range(2000, 2026)]   # 2000/01 to 2025/26
DIVISIONS = ("SC0", "SC1")                                                   # Premiership, Championship

for div in DIVISIONS:
    for season in SEASONS:
        name = f"{div}_{season}.csv"
        if os.path.exists(name):
            continue
        urllib.request.urlretrieve(f"https://www.football-data.co.uk/mmz4281/{season}/{div}.csv", name)
        print("saved", name)
        time.sleep(0.5)                                                      # be polite to their server
print("All", len(DIVISIONS) * len(SEASONS), "files are here.")

It needs only Python 3. Some snippets also need numpy or scipy; each article says so.

Shots with every player's position: StatsBomb open data

The Shot Lab and expected goals from scratch use StatsBomb's free event data: 95,162 shots, each with where every player in the picture was standing. Get it from their open-data repository on GitHub; the article explains which files it reads. StatsBomb's terms ask for a credit and no commercial use. Only the fitted model is published here, never their data.

StatsBomb

Data: StatsBomb open data. The analysis is ours, not StatsBomb's. For education.

Published here

manager-changes-spfl.csv: 131 in-season managerial changes in the Scottish top flight, 2000/01 to 2025/26, compiled for Does sacking the manager bring a bounce? from each season's Wikipedia page, with the source for each row. 2010/11 is missing; that page has no table.