Pulling Election Count data out of Google Sheets for fun and democracy

Andrew Bolster

Senior R&D Manager (Data Science) at Synopsys Software Integrity Group and Treasurer at Farset Labs & Bsides Belfast

Messing around with Elections NI data

Sources:

Creating your own Google Sheet and referencing the crowdsourced data

The above linked spreadsheets are naturally not editable by everyone; this is great for reliable data but isn’t so great when you want to make pretty graphs.

Google Sheets supports the live referencing of external sheets in your own sheets, so you can ‘import’ the data from the read-only sheets as they evolve over the count, and then reference those data in your own visualisations.

This is done using the IMPORTRANGE function in Google Sheets, so like this;

=IMPORTRANGE("https://docs.google.com/spreadsheets/d/1AazeIZwfflJJoTiYNil3RprIOXcNy8yyzfZ4ImVlETA/edit#gid=372848906","Belfast South/West!A2:Q24")

Image of Imported Spreadsheet showing separated results for the Belfast South Assembly Election in 2022

Using this and the Google QUERY language, you can easily create some pretty dynamic graphs in a couple of lines/cells across your own sheets, all while being ‘fed’ by the main collaborative work.

Image of PieChart of First Preference Votes in Belfast South in 2022

For instance, this is generated from the following formula;

=query('Basic IMPORTRANGE'!A2:Q16, "select B, sum(C) group by B order by sum(C) desc");

In this case the first argument to the query is a reference to my own sheet that just has ‘IMPORTRANGE’ in it; the interesting bit is the second argument which gives a list of the values in column B (The Party Names in the count sheet) sorted by the sum of the matching rows in column C (the first preference votes), with that ‘sum’ being defined across the groups with the same values in column B, and finally, these all sorted in a descending fashion by the total of those first preference votes.

So now we’ve easily set up a aggregation with two ‘cells’ of formula and a fairly basic chart.

Doing the real work with Python

Python is really powerful for this kind of stuff, particularly the pandas data management library; we can get the above referenced sheet into a ‘raw’ python format with just a ‘few lines of code’.

import pandas as pd
from urllib.parse import quote

sheet_id = "1AazeIZwfflJJoTiYNil3RprIOXcNy8yyzfZ4ImVlETA" # This is the bit taken from the URL above, like IMPORTRANGE above
tab_id = 372848906
# https://docs.google.com/spreadsheets/d/1AazeIZwfflJJoTiYNil3RprIOXcNy8yyzfZ4ImVlETA/edit#gid=372848906

url = f"https://docs.google.com/spreadsheets/d/{sheet_id}/export?format=csv&gid={tab_id}"
pd.read_csv(url)
Unnamed: 0 Unnamed: 1 Unnamed: 2 Unnamed: 3 Unnamed: 4 Unnamed: 5 Unnamed: 6 Unnamed: 7 Unnamed: 8 Unnamed: 9 ... Unnamed: 17 Unnamed: 18 Unnamed: 19 Unnamed: 20 Unnamed: 21 Unnamed: 22 Unnamed: 23 Unnamed: 24 Unnamed: 25 Unnamed: 26
0 Belfast South NaN Stage 1 Surplus Hargey 2.00 Exclude <500 3.00 Exclude McCann Sibanda 4.00 Exclude Girvin ... NaN NaN NaN NaN NaN 11.00 12.0 13.0 14.0 15.0
1 Deirdre Hargey Sinn Féin 9511 -1687 7824.00 NaN 7824.00 NaN 7824.00 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 Edwin Poots Democratic Unionist Party 7211 6.12 7217.12 6.08 7223.20 117.72 7340.92 1134 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 Matthew O'Toole Social Democratic and Labour Party 5394 664.92 6058.92 68.18 6127.10 322.04 6449.14 10.18 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 Paula Bradshaw Alliance Party 6503 265.14 6768.14 59.5 6827.64 135.82 6963.46 31 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5 Kate Nicholl Alliance Party 5201 145.98 5346.98 57.52 5404.50 131.28 5535.78 17 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
6 Clare Bailey Green Party 4058 167.4 4225.40 169.82 4395.22 490.54 4885.76 48.36 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
7 Stephen McCarthy Ulster Unionist Party 3061 6.12 3067.12 17.72 3084.84 25.18 3110.02 643.36 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
8 Elsie Trainor Social Democratic and Labour Party 2030 181.8 2211.80 18.52 2230.32 132.94 2363.26 4 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
9 Andrew Girvin Traditional Unionist Voice 1935 0.36 1935.36 9 1944.36 35.54 1979.90 -1979.9 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
10 Luke McCann Aontú 806 70.92 876.92 15.16 892.08 -892.08 0.00 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
11 Sipho Sibanda People Before Profit 629 40.5 669.50 172.66 842.16 -842.16 0.00 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
12 Neil Moore Socialist Party 353 18 371.00 -371 0.00 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
13 Paddy Lynn The Workers Party 139 24.48 163.48 -163.48 0.00 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
14 Elly Odhiambo Independent 107 6.84 113.84 -113.84 0.00 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
15 Exhausted NaN NaN 88.42 88.42 54.16 142.58 343.18 485.76 92 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
16 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
17 Eligible Voters 73497 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
18 Turnout 47306 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
19 % Turnout 64.36% NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
20 Valid Ballots 46938 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
21 invalid ballots 368 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
22 quota 7824 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
23 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
24 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
25 Belfast West NaN Stage 1 Surplus Baker 2.00 Exclude Hill Mallon 3.00 Exclude Crossan 4.00 Exclude Burns ... Exclude Doran 9.00 Exclude Murphy Higgins 10.00 Exclude Doherty 11.00 NaN NaN NaN NaN
26 Danny Baker Sinn Féin 9011 -1733 7278.00 NaN 7278.00 NaN 7278.00 NaN ... NaN 7278.00 NaN 7278.00 NaN 7278.00 NaN NaN NaN NaN
27 Órlaithí Flynn Sinn Féin 6743 344.47 7087.47 5.38 7092.85 16.09 7108.94 27.37 ... 68.37 7228.63 179 7407.63 NaN 7407.63 NaN NaN NaN NaN
28 Aisling Reilly Sinn Féin 5681 1028.47 6709.47 10.19 6719.66 7.76 6727.42 17.09 ... 50.52 6811.98 318.98 7130.96 533 7663.96 NaN NaN NaN NaN
29 Pat Sheehan Sinn Féin 6370 52.44 6422.44 4 6426.44 5 6431.44 8.38 ... 26.71 6477.10 258.18 6735.28 451.13 7186.41 NaN NaN NaN NaN
30 Gerry Carroll People Before Profit 3279 115.33 3394.33 19.76 3414.09 78.38 3492.47 70.08 ... 238.23 3936.16 542.99 4479.15 1543.46 6022.61 NaN NaN NaN NaN
31 Frank McCoubrey Democratic Unionist Party 4166 0.57 4166.57 7.19 4173.76 0 4173.76 2 ... 76.19 5275.14 154 5429.14 60.57 5489.71 NaN NaN NaN NaN
32 Paul Doherty Social Democratic and Labour Party 2528 88.35 2616.35 2.19 2618.54 29.14 2647.68 36.28 ... 478.51 3232.66 404.28 3636.94 -3636.94 0.00 NaN NaN NaN NaN
33 Gerard Herdman Aontú 1753 8.17 1761.17 32 1793.17 9.19 1802.36 17.19 ... 35.19 1871.74 -1871.74 0.00 NaN NaN NaN NaN NaN NaN
34 Dan Murphy Irish Republican Socialist Party 1103 12.16 1115.16 8 1123.16 7 1130.16 14 ... 7 1159.16 -1159.16 0.00 NaN NaN NaN NaN NaN NaN
35 Donnamarie Higgins Alliance Party 907 17.48 924.48 2 926.48 6 932.48 7.19 ... -1134.81 0.00 NaN NaN NaN NaN NaN NaN NaN NaN
36 Jordan Doran Traditional Unionist Voice 802 0.38 802.38 3 805.38 1 806.38 3 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
37 Linsey Gibson Ulster Unionist Party 474 0.76 474.76 2 476.76 1.19 477.95 2 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
38 Stevie Maginn Green Party 307 3.04 310.04 3 313.04 10 323.04 10.19 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
39 Gerard Burns Independent 192 16.91 208.91 28.19 237.10 7 244.10 -244.1 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
40 Patrick Crossan The Workers Party 193 4.75 197.75 6.76 204.51 -204.51 0.00 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
41 Tony Mallon Independent 129 2.28 131.28 -131.28 0.00 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
42 Declan Hill Independent 26 0.38 26.38 -26.38 0.00 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
43 Exhausted NaN NaN 37.06 37.06 24 61.06 26.76 87.82 29.33 ... 154.09 393.43 1173.47 1566.90 1048.78 2615.68 NaN NaN NaN NaN
44 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
45 Eligible Voters 68727 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
46 Turnout 44440 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
47 % Turnout 64.66% NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
48 Valid Ballots 43664 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
49 invalid ballots 776 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
50 quota 7278 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

51 rows × 27 columns

This is a little bit more complicated than other google foo would have you believe but it looks like Google updated their API’s over the years to remove the ‘happy path’ for this call.

Additionally, note that as in the IMPORTRANGE example, there are no usable ‘headers’ in the underlying data so we may have to create these ourselves for more complex analysis.

Also, we have to manually ‘tidy up’ the ‘range’ ourselves, as the Belfast South range only goes to row 24, and then Belfast West appears.

While we could get fancy, for simplicity, this is a manual example. And we’ll also exclude the ‘metadata’ such as the Turnout statistics and Quota from the bottom of the section, so in this case trimming the data from to run between rows 3 and 17 for just candidates and transfer statistics.

df = pd.read_csv(url)
df
Unnamed: 0 Unnamed: 1 Unnamed: 2 Unnamed: 3 Unnamed: 4 Unnamed: 5 Unnamed: 6 Unnamed: 7 Unnamed: 8 Unnamed: 9 ... Unnamed: 17 Unnamed: 18 Unnamed: 19 Unnamed: 20 Unnamed: 21 Unnamed: 22 Unnamed: 23 Unnamed: 24 Unnamed: 25 Unnamed: 26
0 Belfast South NaN Stage 1 Surplus Hargey 2.00 Exclude <500 3.00 Exclude McCann Sibanda 4.00 Exclude Girvin ... NaN NaN NaN NaN NaN 11.00 12.0 13.0 14.0 15.0
1 Deirdre Hargey Sinn Féin 9511 -1687 7824.00 NaN 7824.00 NaN 7824.00 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 Edwin Poots Democratic Unionist Party 7211 6.12 7217.12 6.08 7223.20 117.72 7340.92 1134 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 Matthew O'Toole Social Democratic and Labour Party 5394 664.92 6058.92 68.18 6127.10 322.04 6449.14 10.18 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 Paula Bradshaw Alliance Party 6503 265.14 6768.14 59.5 6827.64 135.82 6963.46 31 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5 Kate Nicholl Alliance Party 5201 145.98 5346.98 57.52 5404.50 131.28 5535.78 17 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
6 Clare Bailey Green Party 4058 167.4 4225.40 169.82 4395.22 490.54 4885.76 48.36 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
7 Stephen McCarthy Ulster Unionist Party 3061 6.12 3067.12 17.72 3084.84 25.18 3110.02 643.36 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
8 Elsie Trainor Social Democratic and Labour Party 2030 181.8 2211.80 18.52 2230.32 132.94 2363.26 4 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
9 Andrew Girvin Traditional Unionist Voice 1935 0.36 1935.36 9 1944.36 35.54 1979.90 -1979.9 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
10 Luke McCann Aontú 806 70.92 876.92 15.16 892.08 -892.08 0.00 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
11 Sipho Sibanda People Before Profit 629 40.5 669.50 172.66 842.16 -842.16 0.00 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
12 Neil Moore Socialist Party 353 18 371.00 -371 0.00 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
13 Paddy Lynn The Workers Party 139 24.48 163.48 -163.48 0.00 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
14 Elly Odhiambo Independent 107 6.84 113.84 -113.84 0.00 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
15 Exhausted NaN NaN 88.42 88.42 54.16 142.58 343.18 485.76 92 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
16 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
17 Eligible Voters 73497 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
18 Turnout 47306 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
19 % Turnout 64.36% NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
20 Valid Ballots 46938 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
21 invalid ballots 368 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
22 quota 7824 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
23 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
24 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
25 Belfast West NaN Stage 1 Surplus Baker 2.00 Exclude Hill Mallon 3.00 Exclude Crossan 4.00 Exclude Burns ... Exclude Doran 9.00 Exclude Murphy Higgins 10.00 Exclude Doherty 11.00 NaN NaN NaN NaN
26 Danny Baker Sinn Féin 9011 -1733 7278.00 NaN 7278.00 NaN 7278.00 NaN ... NaN 7278.00 NaN 7278.00 NaN 7278.00 NaN NaN NaN NaN
27 Órlaithí Flynn Sinn Féin 6743 344.47 7087.47 5.38 7092.85 16.09 7108.94 27.37 ... 68.37 7228.63 179 7407.63 NaN 7407.63 NaN NaN NaN NaN
28 Aisling Reilly Sinn Féin 5681 1028.47 6709.47 10.19 6719.66 7.76 6727.42 17.09 ... 50.52 6811.98 318.98 7130.96 533 7663.96 NaN NaN NaN NaN
29 Pat Sheehan Sinn Féin 6370 52.44 6422.44 4 6426.44 5 6431.44 8.38 ... 26.71 6477.10 258.18 6735.28 451.13 7186.41 NaN NaN NaN NaN
30 Gerry Carroll People Before Profit 3279 115.33 3394.33 19.76 3414.09 78.38 3492.47 70.08 ... 238.23 3936.16 542.99 4479.15 1543.46 6022.61 NaN NaN NaN NaN
31 Frank McCoubrey Democratic Unionist Party 4166 0.57 4166.57 7.19 4173.76 0 4173.76 2 ... 76.19 5275.14 154 5429.14 60.57 5489.71 NaN NaN NaN NaN
32 Paul Doherty Social Democratic and Labour Party 2528 88.35 2616.35 2.19 2618.54 29.14 2647.68 36.28 ... 478.51 3232.66 404.28 3636.94 -3636.94 0.00 NaN NaN NaN NaN
33 Gerard Herdman Aontú 1753 8.17 1761.17 32 1793.17 9.19 1802.36 17.19 ... 35.19 1871.74 -1871.74 0.00 NaN NaN NaN NaN NaN NaN
34 Dan Murphy Irish Republican Socialist Party 1103 12.16 1115.16 8 1123.16 7 1130.16 14 ... 7 1159.16 -1159.16 0.00 NaN NaN NaN NaN NaN NaN
35 Donnamarie Higgins Alliance Party 907 17.48 924.48 2 926.48 6 932.48 7.19 ... -1134.81 0.00 NaN NaN NaN NaN NaN NaN NaN NaN
36 Jordan Doran Traditional Unionist Voice 802 0.38 802.38 3 805.38 1 806.38 3 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
37 Linsey Gibson Ulster Unionist Party 474 0.76 474.76 2 476.76 1.19 477.95 2 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
38 Stevie Maginn Green Party 307 3.04 310.04 3 313.04 10 323.04 10.19 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
39 Gerard Burns Independent 192 16.91 208.91 28.19 237.10 7 244.10 -244.1 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
40 Patrick Crossan The Workers Party 193 4.75 197.75 6.76 204.51 -204.51 0.00 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
41 Tony Mallon Independent 129 2.28 131.28 -131.28 0.00 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
42 Declan Hill Independent 26 0.38 26.38 -26.38 0.00 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
43 Exhausted NaN NaN 37.06 37.06 24 61.06 26.76 87.82 29.33 ... 154.09 393.43 1173.47 1566.90 1048.78 2615.68 NaN NaN NaN NaN
44 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
45 Eligible Voters 68727 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
46 Turnout 44440 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
47 % Turnout 64.66% NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
48 Valid Ballots 43664 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
49 invalid ballots 776 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
50 quota 7278 NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

51 rows × 27 columns

df.iloc[1:16]
Unnamed: 0 Unnamed: 1 Unnamed: 2 Unnamed: 3 Unnamed: 4 Unnamed: 5 Unnamed: 6 Unnamed: 7 Unnamed: 8 Unnamed: 9 ... Unnamed: 17 Unnamed: 18 Unnamed: 19 Unnamed: 20 Unnamed: 21 Unnamed: 22 Unnamed: 23 Unnamed: 24 Unnamed: 25 Unnamed: 26
1 Deirdre Hargey Sinn Féin 9511 -1687 7824.00 NaN 7824.00 NaN 7824.00 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 Edwin Poots Democratic Unionist Party 7211 6.12 7217.12 6.08 7223.20 117.72 7340.92 1134 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 Matthew O'Toole Social Democratic and Labour Party 5394 664.92 6058.92 68.18 6127.10 322.04 6449.14 10.18 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 Paula Bradshaw Alliance Party 6503 265.14 6768.14 59.5 6827.64 135.82 6963.46 31 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5 Kate Nicholl Alliance Party 5201 145.98 5346.98 57.52 5404.50 131.28 5535.78 17 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
6 Clare Bailey Green Party 4058 167.4 4225.40 169.82 4395.22 490.54 4885.76 48.36 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
7 Stephen McCarthy Ulster Unionist Party 3061 6.12 3067.12 17.72 3084.84 25.18 3110.02 643.36 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
8 Elsie Trainor Social Democratic and Labour Party 2030 181.8 2211.80 18.52 2230.32 132.94 2363.26 4 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
9 Andrew Girvin Traditional Unionist Voice 1935 0.36 1935.36 9 1944.36 35.54 1979.90 -1979.9 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
10 Luke McCann Aontú 806 70.92 876.92 15.16 892.08 -892.08 0.00 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
11 Sipho Sibanda People Before Profit 629 40.5 669.50 172.66 842.16 -842.16 0.00 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
12 Neil Moore Socialist Party 353 18 371.00 -371 0.00 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
13 Paddy Lynn The Workers Party 139 24.48 163.48 -163.48 0.00 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
14 Elly Odhiambo Independent 107 6.84 113.84 -113.84 0.00 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
15 Exhausted NaN NaN 88.42 88.42 54.16 142.58 343.18 485.76 92 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

15 rows × 27 columns

There are a few ways to tidy up this stage/transfer setup, so for simplicity we’ll take the ‘index’ off the left of the table (consisting of the candidate and party names) and try and construct a new column index based on those.

Sounds fancy.

df.iloc[1:16]
Unnamed: 0 Unnamed: 1 Unnamed: 2 Unnamed: 3 Unnamed: 4 Unnamed: 5 Unnamed: 6 Unnamed: 7 Unnamed: 8 Unnamed: 9 ... Unnamed: 17 Unnamed: 18 Unnamed: 19 Unnamed: 20 Unnamed: 21 Unnamed: 22 Unnamed: 23 Unnamed: 24 Unnamed: 25 Unnamed: 26
1 Deirdre Hargey Sinn Féin 9511 -1687 7824.00 NaN 7824.00 NaN 7824.00 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 Edwin Poots Democratic Unionist Party 7211 6.12 7217.12 6.08 7223.20 117.72 7340.92 1134 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 Matthew O'Toole Social Democratic and Labour Party 5394 664.92 6058.92 68.18 6127.10 322.04 6449.14 10.18 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 Paula Bradshaw Alliance Party 6503 265.14 6768.14 59.5 6827.64 135.82 6963.46 31 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5 Kate Nicholl Alliance Party 5201 145.98 5346.98 57.52 5404.50 131.28 5535.78 17 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
6 Clare Bailey Green Party 4058 167.4 4225.40 169.82 4395.22 490.54 4885.76 48.36 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
7 Stephen McCarthy Ulster Unionist Party 3061 6.12 3067.12 17.72 3084.84 25.18 3110.02 643.36 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
8 Elsie Trainor Social Democratic and Labour Party 2030 181.8 2211.80 18.52 2230.32 132.94 2363.26 4 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
9 Andrew Girvin Traditional Unionist Voice 1935 0.36 1935.36 9 1944.36 35.54 1979.90 -1979.9 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
10 Luke McCann Aontú 806 70.92 876.92 15.16 892.08 -892.08 0.00 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
11 Sipho Sibanda People Before Profit 629 40.5 669.50 172.66 842.16 -842.16 0.00 NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
12 Neil Moore Socialist Party 353 18 371.00 -371 0.00 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
13 Paddy Lynn The Workers Party 139 24.48 163.48 -163.48 0.00 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
14 Elly Odhiambo Independent 107 6.84 113.84 -113.84 0.00 NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
15 Exhausted NaN NaN 88.42 88.42 54.16 142.58 343.18 485.76 92 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

15 rows × 27 columns

_table = df.iloc[1:16]
_table = _table.dropna(how='all', axis=1)
_table = _table.set_index(_table.columns.tolist()[0:2])
_table = _table.fillna(0)
_table = _table.astype(float)
_table.index=_table.index.set_names(['Candidate','Party'])
_table
Unnamed: 2 Unnamed: 3 Unnamed: 4 Unnamed: 5 Unnamed: 6 Unnamed: 7 Unnamed: 8 Unnamed: 9 Unnamed: 10 Unnamed: 11 Unnamed: 12 Unnamed: 13 Unnamed: 14 Unnamed: 15 Unnamed: 16
Candidate Party
Deirdre Hargey Sinn Féin 9511.0 -1687.00 7824.00 0.00 7824.00 0.00 7824.00 0.00 7824.00 0.00 7824.00 0.00 7824.00 0.00 7824.00
Edwin Poots Democratic Unionist Party 7211.0 6.12 7217.12 6.08 7223.20 117.72 7340.92 1134.00 8474.92 0.00 8474.92 0.00 8474.92 -650.92 7824.00
Matthew O'Toole Social Democratic and Labour Party 5394.0 664.92 6058.92 68.18 6127.10 322.04 6449.14 10.18 6459.32 1630.00 8089.32 0.00 8089.32 0.00 8089.32
Paula Bradshaw Alliance Party 6503.0 265.14 6768.14 59.50 6827.64 135.82 6963.46 31.00 6994.46 214.68 7209.14 1114.00 8323.14 0.00 8323.14
Kate Nicholl Alliance Party 5201.0 145.98 5346.98 57.52 5404.50 131.28 5535.78 17.00 5552.78 244.90 5797.68 858.42 6656.10 81.00 6737.10
Clare Bailey Green Party 4058.0 167.40 4225.40 169.82 4395.22 490.54 4885.76 48.36 4934.12 164.02 5098.14 600.96 5699.10 127.00 5826.10
Stephen McCarthy Ulster Unionist Party 3061.0 6.12 3067.12 17.72 3084.84 25.18 3110.02 643.36 3753.38 16.90 3770.28 -3770.28 0.00 0.00 0.00
Elsie Trainor Social Democratic and Labour Party 2030.0 181.80 2211.80 18.52 2230.32 132.94 2363.26 4.00 2367.26 -2367.26 0.00 0.00 0.00 0.00 0.00
Andrew Girvin Traditional Unionist Voice 1935.0 0.36 1935.36 9.00 1944.36 35.54 1979.90 -1979.90 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Luke McCann Aontú 806.0 70.92 876.92 15.16 892.08 -892.08 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Sipho Sibanda People Before Profit 629.0 40.50 669.50 172.66 842.16 -842.16 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Neil Moore Socialist Party 353.0 18.00 371.00 -371.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Paddy Lynn The Workers Party 139.0 24.48 163.48 -163.48 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Elly Odhiambo Independent 107.0 6.84 113.84 -113.84 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Exhausted NaN 0.0 88.42 88.42 54.16 142.58 343.18 485.76 92.00 577.76 96.76 674.52 1196.90 1871.42 442.92 2314.34

Now to do the same thing with the stage counts and transfers;

There are many ways to do this, either leaving it as is and just naming the columns by Stage and Transfer, but a ‘better’ way to do it is to create a multiindex on the column. Which probably means nothing.

_table.columns
Index(['Unnamed: 2', 'Unnamed: 3', 'Unnamed: 4', 'Unnamed: 5', 'Unnamed: 6',
       'Unnamed: 7', 'Unnamed: 8', 'Unnamed: 9', 'Unnamed: 10', 'Unnamed: 11',
       'Unnamed: 12', 'Unnamed: 13', 'Unnamed: 14', 'Unnamed: 15',
       'Unnamed: 16'],
      dtype='object')
stage = ['Count','Transfers']
stages = range(1,_table.shape[1]//2+2)
pd.MultiIndex.from_product([stages,stage])[:-1]
MultiIndex([(1,     'Count'),
            (1, 'Transfers'),
            (2,     'Count'),
            (2, 'Transfers'),
            (3,     'Count'),
            (3, 'Transfers'),
            (4,     'Count'),
            (4, 'Transfers'),
            (5,     'Count'),
            (5, 'Transfers'),
            (6,     'Count'),
            (6, 'Transfers'),
            (7,     'Count'),
            (7, 'Transfers'),
            (8,     'Count')],
           )
_table.columns=pd.MultiIndex.from_product([stages,stage], names=['Stage','Step'])[:-1]
_table
Stage 1 2 3 4 5 6 7 8
Step Count Transfers Count Transfers Count Transfers Count Transfers Count Transfers Count Transfers Count Transfers Count
Candidate Party
Deirdre Hargey Sinn Féin 9511.0 -1687.00 7824.00 0.00 7824.00 0.00 7824.00 0.00 7824.00 0.00 7824.00 0.00 7824.00 0.00 7824.00
Edwin Poots Democratic Unionist Party 7211.0 6.12 7217.12 6.08 7223.20 117.72 7340.92 1134.00 8474.92 0.00 8474.92 0.00 8474.92 -650.92 7824.00
Matthew O'Toole Social Democratic and Labour Party 5394.0 664.92 6058.92 68.18 6127.10 322.04 6449.14 10.18 6459.32 1630.00 8089.32 0.00 8089.32 0.00 8089.32
Paula Bradshaw Alliance Party 6503.0 265.14 6768.14 59.50 6827.64 135.82 6963.46 31.00 6994.46 214.68 7209.14 1114.00 8323.14 0.00 8323.14
Kate Nicholl Alliance Party 5201.0 145.98 5346.98 57.52 5404.50 131.28 5535.78 17.00 5552.78 244.90 5797.68 858.42 6656.10 81.00 6737.10
Clare Bailey Green Party 4058.0 167.40 4225.40 169.82 4395.22 490.54 4885.76 48.36 4934.12 164.02 5098.14 600.96 5699.10 127.00 5826.10
Stephen McCarthy Ulster Unionist Party 3061.0 6.12 3067.12 17.72 3084.84 25.18 3110.02 643.36 3753.38 16.90 3770.28 -3770.28 0.00 0.00 0.00
Elsie Trainor Social Democratic and Labour Party 2030.0 181.80 2211.80 18.52 2230.32 132.94 2363.26 4.00 2367.26 -2367.26 0.00 0.00 0.00 0.00 0.00
Andrew Girvin Traditional Unionist Voice 1935.0 0.36 1935.36 9.00 1944.36 35.54 1979.90 -1979.90 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Luke McCann Aontú 806.0 70.92 876.92 15.16 892.08 -892.08 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Sipho Sibanda People Before Profit 629.0 40.50 669.50 172.66 842.16 -842.16 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Neil Moore Socialist Party 353.0 18.00 371.00 -371.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Paddy Lynn The Workers Party 139.0 24.48 163.48 -163.48 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Elly Odhiambo Independent 107.0 6.84 113.84 -113.84 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Exhausted NaN 0.0 88.42 88.42 54.16 142.58 343.18 485.76 92.00 577.76 96.76 674.52 1196.90 1871.42 442.92 2314.34

Now we can do some interesting queries really easily;

_table.xs("Count", level='Step', axis=1)
Stage 1 2 3 4 5 6 7 8
Candidate Party
Deirdre Hargey Sinn Féin 9511.0 7824.00 7824.00 7824.00 7824.00 7824.00 7824.00 7824.00
Edwin Poots Democratic Unionist Party 7211.0 7217.12 7223.20 7340.92 8474.92 8474.92 8474.92 7824.00
Matthew O'Toole Social Democratic and Labour Party 5394.0 6058.92 6127.10 6449.14 6459.32 8089.32 8089.32 8089.32
Paula Bradshaw Alliance Party 6503.0 6768.14 6827.64 6963.46 6994.46 7209.14 8323.14 8323.14
Kate Nicholl Alliance Party 5201.0 5346.98 5404.50 5535.78 5552.78 5797.68 6656.10 6737.10
Clare Bailey Green Party 4058.0 4225.40 4395.22 4885.76 4934.12 5098.14 5699.10 5826.10
Stephen McCarthy Ulster Unionist Party 3061.0 3067.12 3084.84 3110.02 3753.38 3770.28 0.00 0.00
Elsie Trainor Social Democratic and Labour Party 2030.0 2211.80 2230.32 2363.26 2367.26 0.00 0.00 0.00
Andrew Girvin Traditional Unionist Voice 1935.0 1935.36 1944.36 1979.90 0.00 0.00 0.00 0.00
Luke McCann Aontú 806.0 876.92 892.08 0.00 0.00 0.00 0.00 0.00
Sipho Sibanda People Before Profit 629.0 669.50 842.16 0.00 0.00 0.00 0.00 0.00
Neil Moore Socialist Party 353.0 371.00 0.00 0.00 0.00 0.00 0.00 0.00
Paddy Lynn The Workers Party 139.0 163.48 0.00 0.00 0.00 0.00 0.00 0.00
Elly Odhiambo Independent 107.0 113.84 0.00 0.00 0.00 0.00 0.00 0.00
Exhausted NaN 0.0 88.42 142.58 485.76 577.76 674.52 1871.42 2314.34

This makes plotting quite simple; which then makes the queries you can express much more complex…

_table.xs("Count", level='Step', axis=1).groupby('Party').sum().T.plot()
<Axes: xlabel='Stage'>

png

_table.xs("Transfers", level='Step', axis=1)\
    .groupby('Party').sum().cumsum().T.plot(
        title='Net Cumulative Transfers'
    )\
    .legend(loc='right', bbox_to_anchor=(1.6,0.5))
<matplotlib.legend.Legend at 0x17b555a50>

png

Conclusion

Considering it’s election day today in Northern Ireland, I wanted to bash this out to help other election observers have a play with the fantastic work the likes of @colm_burns and the rest of the @electionsni team are doing.

More than happy to help anyone else answer interesting electoral questions, and remember; vote early, vote often, and #votetillyouboke

Published: May 18 2023

  • category:
  • tags:
blog comments powered by Disqus