Methodology

This page documents every formula, source, and editorial choice on the site. Read it before you cite us. If you find an error, mail [email protected] and a correction will be published with date, diff, and impact.

Editorial frame

Every page on this site is structured to make the voting method the subject of the observation, not the individual elected on it. We name candidates because the public election record names them; we make no claim about any individual candidate's conduct, fitness for office, or character. The factual claim — "won X% of valid ballots" — is verifiable from the source data linked on /data.

We deliberately avoid the words "majority" and "minority" as system labels. They imply that First-Past-the-Post and bloc vote have a numerical threshold a winner must clear — which they do not. A candidate wins under these methods by being top of the poll, full stop, regardless of share. Instead we report each elected candidate's share against the proportional quota — the share that would be needed to be guaranteed that seat under a voting method that allocates seats in proportion to votes — and call out the gap.

Where seats are allocated proportionally to votes, results like the ones on this site do not occur: the proportional quota is the floor that any common proportional method requires. The contrast between First-Past-the-Post / bloc vote and a proportional alternative is the rhetorical hook of the project, and the editorial frame throughout.

What counts as "proportional"? The quota threshold applies to any method whose overall seat allocation tracks the vote distribution — STV, list PR (D'Hondt, Sainte-Laguë, and similar), proportional approval, and the regional-list portion of mixed-member systems like AMS. Mixed-member systems are partly First-Past-the-Post in their constituency component, but their compensatory list seats restore overall proportionality, so the quota framing is still the right benchmark for the system as a whole. We deliberately don't single out one preferred method elsewhere on the site — the editorial argument is against the distortion, not for one particular replacement.

Picking the right replacement is exactly what a National Commission on Electoral Representation would be for. The data on this site documents the case for one.

Winning percentage

For a single-member ward, winning_pct = winner_votes / valid_ballots.

For a multi-member ward (electing N councillors at once under bloc vote), each elected candidate has their own candidate_votes / valid_ballots. We headline the most-marginal of the elected candidates — the seat-holder with the thinnest mandate in that ward — because that figure shows how little support the weakest seat-winner actually attracted. Per-candidate shares are also visible in the candidate table on every council page.

valid_ballots = ballots_cast − invalid_votes. This matches the House of Commons Library "Valid vote turnout (HoC method)" definition in the source workbook.

A note on multi-member wards

In a multi-member ward (electing N councillors at once under bloc vote), each voter may cast up to N votes — so a candidate's candidate_votes / valid_ballots ratio understates the share of voters who supported them, sometimes by a lot. We report the ratio anyway, with the same denominator as single-member wards, because (a) it is the figure used by the source workbook and consistently comparable across ward types, and (b) any other choice would require speculating about how voters distributed their second and third votes. Readers interpreting multi-member percentages should treat them as a lower bound on candidate support, not an upper one. The proportional quota framing (above) is calibrated to this same denominator, so the comparison stays apples-to-apples.

Proportional quota and "under par"

The proportional quota is the share of valid ballots a candidate would need to be guaranteed a seat under any common proportional voting method: quota = 1 seats + 1. For a 1-seat ward this collapses to 50% (a true majority); for 2 seats it is 33.3%; for 3 seats, 25%. (Technical name for the curious: the Droop quota, after H. R. Droop's 1869 paper on proportional election methods. The figure is used, in the same or near-identical form, by every preferential and party-list system we are aware of.)

For each race we compute under_par = quota − winning_pct. A positive value means the marginal elected candidate won less of the valid ballots than the quota — the seat would not have been guaranteed under a proportional count. We surface this as "X.X points below quota" and treat it as the editorial indictment of the voting method, not the candidate. Above-quota results are mathematically clean and pass without comment.

This is a deliberate departure from the older "minority winner" framing (winning_pct < 50%). The 50% threshold is not a rule of First-Past-the-Post or bloc vote — calling someone a "minority winner" implies they fell short of a standard the system never required of them. The quota framing is the standard a proportional system does require, and the gap is the loss attributable to the method.

"If votes were counted by party"

On every council page we show how the seats would be distributed if the party vote totals were allocated proportionally rather than via First-Past-the-Post. The arithmetic uses the D'Hondt method — the most widely-used party-list proportional algorithm worldwide (used by the European Parliament, the Scottish Parliament regional list, the Welsh Senedd regional list, and the London Assembly). It allocates seats one at a time to the party with the highest quotient party votes (seats already won) + 1, repeating until all seats are filled.

Caveat — bloc vote inflation. In a multi-member ward (electing N councillors at once under bloc vote), each voter may cast up to N votes — so parties that ran a full slate get up to N× the votes of parties that ran a single candidate. Aggregating "candidate votes by party" therefore over-counts parties with full slates and under-counts parties with partial ones. Treat the proportional column as a directional proxy for what a list-PR system would deliver, not a strict counterfactual. A preferential proportional method that counts voter rankings would avoid this distortion, but the LEH data does not record voter rankings so we cannot reproduce that allocation here.

Cycle-over-cycle comparison

Each council overview page (/[council]) compares the council across every cycle in our data. Three views:

Council reorganisations

Eleven councils in our window were created or abolished by the 2019–2023 wave of UK local-government reorganisation. Where that applies, the council overview page carries an explicit warning banner explaining what happened and when, and listing the predecessor or successor councils. The list is hand-curated from the Wikipedia record of the LGR wave, cross-checked against the Commons Library briefing CBP-9056. The next wave (Surrey 2026, Essex 2027/28) will be added when those cycles enter the dataset.

System anomalies

Two anomaly lenses are surfaced as their own pages:

Other classical FPTP anomalies — smallest absolute winning vote count, party second in vote share winning the most seats per council, vote-share-to-seat-share inversions, multi-member wards electing a third-placed party's candidate, high-turnout wards with low-mandate winners — are computable from the SQLite database but not yet surfaced as their own lenses on the site.

Sources

All cycles below are ingested from the Local Election Handbook (LEH) for the relevant year, published by the House of Commons Library under the Open Parliament Licence. Workbooks live in the repo at docs/LEH-{2021..2025}-results-HoC*.xlsx; the per-year ETL adapter normalises sheet-name and column-name drift across years.

For the 2026-05-07 cycle, the eventual Commons Library Local Election Handbook for that year will be the canonical source.

Reproducibility

Every number on the published site is derivable from the SQLite database on /data using standard SQL. The schema documentation on that page lists every table and column. The site build is deterministic: the same git commit and the same source data produce the same published bytes.

What is not here yet

Errata

No errata recorded yet. When a methodological correction is required, an entry will be published here with a date, a one-paragraph explanation, the diff (what number changed, by how much), and the affected pages.