One cell is one riding. Choose any recorded division between
2025-05-29 and 2026-06-18 and the chamber recolours
to how each seat voted on it. Of the 59,242 positions cast,
43 went against the voter’s own party.
This is not all of Parliament. It is the 173 times the House recorded
who was on which side — see Method.
01 · The chamber
Pick a vote.
Yea and nay are drawn at the same weight. One is the
filled square, the other is the ring of the same square, in the same party colour.
Neither is brighter than the other, because the design is not permitted to imply which
vote was the right one. The only brightness on this grid is
a member voting against the majority of their own
party, which is the single thing the accent colour on this site is reserved for.
02 · The exceptions
Almost nobody breaks ranks.
Party discipline in the Canadian House is close to total, so the measurement worth
making is not how often members agree but how rarely they do not. Across
173 divisions there were 43 dissenting
positions, on 15 divisions, from
37 seats. The other
59,199 went with the party.
Every division number links to its page on openparliament.ca, which is
the source this page is built from and carries the roll call in full. The
dissent flag is computed there, not here: it is true when a member’s
vote differs from the majority position of their own party on that division. A party of
one cannot dissent from itself, which is why the independent and very small
caucuses contribute almost nothing to this table.
03 · Method
What this counts, and what it leaves out.
The unit is the riding, not the member. There are 343 ridings and
they do not move; members do. Over a session some seats change hands, and a grid keyed
to members would have to grow or shrink or lie. Keyed to ridings it is 343 cells
throughout, and a seat that changed hands shows the vote of whoever held it that day.
Checked at build across all 59,242 positions: there is no case of two members
mapping to the same riding on the same division.
This page shows recorded divisions only —
173 of them. The great majority of House business passes on voice votes,
on unanimous consent, or at committee, and produces no per-member record at all. A grid
that felt like a complete picture of Parliament would be the most misleading object on
this site, so it says the number in its first sentence and says this here.
The totals are checked against a second source in the same database.bills_votequestion stores its own yea, nay and paired totals, written
independently of the per-member rows. The build recomputes all three from the grid and
compares. All 173 divisions agree. If any did not, this page would fail
to generate rather than ship a picture that disagrees with the numbers printed beside
it.
Absence is not abstention.bills_membervote.vote is one
of Y, N, P or A. A means
no vote was recorded for that seat — travel, illness, ministerial business, the
chair. It is not a stance, so it is drawn as the absence of a mark rather than as a
fourth position.
4 seats are vacant as of the snapshot, drawn as an
empty outline: Chicoutimi—Le Fjord (QC), Saint-Hyacinthe—Bagot—Acton (QC), Beaches—East York (ON), North Vancouver—Capilano (BC). A vacancy
is kept distinct from a member who did not vote; collapsing the two would overstate
absence by exactly the number of empty seats. One of them,
Beaches—East York, has its own page
on this site.
Reading order is sourced, not invented. Provinces run in the
official Statistics Canada geographical order — east to west, then the three
territories — and ridings run alphabetically inside each. No ordering on this page
carries a judgement.
Party colour is identity only. Display values are raised in lightness
from the parties’ official brand values so that none is louder than another on a
dark ground, and they are read out of this site’s stylesheet at build time rather
than retyped here. Both are printed below.
Party
Seats
Display
Official
Liberal
172
#e8555c
#D71920
Conservative
139
#5c8fd6
#142F52
Bloc
21
#51a5e1
#080236
NDP
5
#f58220
#F58220
Independent
1
#9a958a
—
Green
1
#3fbf63
#20A242
Vacant
4
—
—
The encoding. Each division carries one
string of 343 characters, one per seat, in the fixed order the grid is drawn in.
Y yea · N nay ·
P paired · A no vote recorded ·
. seat vacant that day. It is the smallest honest encoding and the
easiest one to check by hand: the whole page is in the JSON at the bottom of this
document.
The three queries, in full:
SELECT r.id, r.name_en, r.province, r.edid,
COALESCE(p.short_name_en,''), COALESCE(pol.name,''), COALESCE(pol.slug,'')
FROM core_riding r
LEFT JOIN core_electedmember m ON m.riding_id = r.id AND m.end_date IS NULL
LEFT JOIN core_party p ON p.id = m.party_id
LEFT JOIN core_politician pol ON pol.id = m.politician_id
WHERE r.current
ORDER BY r.province, r.name_en
;
SELECT vq.id, vq.number, vq.date::text, vq.result, vq.yea_total, vq.nay_total,
vq.paired_total, COALESCE(b.number_only::text,''), COALESCE(b.number,''),
replace(replace(vq.description_en, E'\t', ' '), E'\n', ' ')
FROM bills_votequestion vq
LEFT JOIN bills_bill b ON b.id = vq.bill_id
WHERE vq.session_id = '45-1'
ORDER BY vq.date, vq.number
;
SELECT vq.id, em.riding_id, mv.vote, mv.dissent
FROM bills_membervote mv
JOIN bills_votequestion vq ON vq.id = mv.votequestion_id
JOIN core_electedmember em ON em.id = mv.member_id
WHERE vq.session_id = '45-1'