Vote Splitting in Alberta

Posted in civics on Wednesday, May 06 2015

Alberta's big election was last night, and an orange wave overcame the province resulting in an NDP majority. This ends the 44 year reign of the Progressive Conservative party, and marks the fourth change in government in Alberta, ever, in 110 years. Yes only 4.

Anyways. For a long time, on the left, it was a constant bicker that if only the left wing parties could combine, Voltron style, they could defeat the PCs. Since there was really only 1 right wing party, until the Wildrose party came along, and there were >2 left wing parties (depending on how you defined viable), votes for the left in aggregate could out number the PCs and yet the PCs take all the seats.

In a delightful turn of schadenfreude, the right is now experiencing this as, in terms of popular vote, the Wildrose and the PCs combined had a majority yet the NDP won the majority of the seats.

This is one of the problems with first-passed-the-post elections, often popular vote does not translate into seats. This is also why the PCs, while they have a greater share of the popular vote, have almost half the seats than the Wildrose. cough election reform cough.

Since the election data from last night is on ze internets, and I have a computer, I quickly took a boo after work today to see how much vote splitting on the right played a part.

I assume that all the people who voted for Wildrose would have voted PC, if the Wildrose didn't exist, and that all the folks in the major leftwing parties would not have voted for some nebulous left wing party. These are big assumptions are are not true in reality!

import pandas as pd
from pandas.io.html import read_html

# import the elections result table
elections_url = 'http://results.elections.ab.ca/wtResultsPGE.htm'
dfs = read_html(elections_url)


# trim off the cruft that came along for the ride
df = dfs[0][2:]
df.columns = df.iloc[0]
df = df.drop([2,3,91])
df = df.drop('ED', 1)

# all empty results are zero votes
df.fillna(0, inplace=True)
df = df.convert_objects(convert_numeric=True)

df.head()
2 ED Name PollsReporting AFP LIB AP SC CP-A GPA NDP PC WRP IND
4 DUNVEGAN-CENTRAL PEACE-NOTLEY 58 of 58 0 0 0 0 0 0 3694 2756 3143 0
5 LESSER SLAVE LAKE 65 of 65 0 0 0 0 0 0 3908 1950 3196 0
6 CALGARY-ACADIA 72 of 72 0 764 0 0 0 0 5503 4604 4981 0
7 CALGARY-BOW 75 of 75 0 683 466 0 0 447 5680 5417 3753 0
8 CALGARY-BUFFALO 78 of 78 0 3274 0 0 0 263 4671 3740 1354 0
# if all the left wing parties fused into Voltron
df['left'] = df['LIB'] + df['AP'] + df['GPA'] + df['NDP']

# if all the PC party absorbed the Wildrose like an Amoeba
df['right'] = df['PC'] + df['WRP']

# would there still have been an orange wave?
df['orange-wave'] = df['left'] > df['right']
df['orange-wave'].value_counts()

 

False    53
True     34
dtype: int64

So, in short, the orange wave would have evaporated and a clear conservative majority would have won with 53 seats to 34.

As always the ipython notebook can be found here