How local are party candidates for the Lambeth council elections?

Getting annoyed by timewasters

During the Brixton Hill by-election campaign a few years ago I attended a hustings organised by Brixton blog. I got pretty annoyed by how candidates from some parties used the event (and the campaign) to parrot their parties’ national and international policies.

The Socialist Party called for full communism as the solution to pretty much every local issue. For most issues UKIP demanded we leave the EU. When the UKIP candidate did address local issues her positions (such as promoting private car use) seemed very strange for a Brixton local. It turned out she lived in Clapham. I wrote a blog post about it at the time where I plotted the candidates addresses on a map relative to the ward and council boundaries.

Ranking parties on how local their candidates are

This time around the whole borough has council elections and I was wondering if a similar trend exists. Visualising each ward doesn’t seem as useful as there are 289 candidates standing so instead I ranked the parties using a simple scheme: The percentage of candidates who live in the same ward they are standing in.

Parties ranked by % of candidates who live in the ward in which they are standing
Rank Party % of Candidates who live in ward Local Candidates Total Candidates
1 The Pirate Party 100% 1 1
2 The Green Party 67% 42 62
3 Independent 50% 2 4
4 Liberal Democrats 49% 31 63
5 Labour Party 47% 30 63
6 Conservative Party 46% 29 63
7 UK Independence Party (UKIP) 35% 6 17
8 Trade Unionists and Socialists Coalition 30% 4 13
9 The Socialist Party (GB) 0% 0 3

The Pirate Party only having a single candidate obviously helps them come first. I suspect the Green Party’s high ranking reflects their decentralized local nature (Disclaimer: I’m going to vote for them). On the bottom of the list are the The Socialist Party (GB). None of the Socialist Party’s candidates live locally (in fact none of them live in Lambeth at all – they hail from Kingston, Bromley and Richmond).

UKIP and the Trade Unionists and Socialists Coalition are predictably on the bottom end of the table. The big three traditional parties sit in the middle, possibly reflecting their tendency to ‘parachute’ in candidates to wards.

The gory technical details

There should be open data on who is standing in elections right? Well if there is I couldn’t find it. Instead I downloaded the PDFs that listed candidates from Lambeth website. I used the the command line version of Tabula to extract the data. I then geocoded the data using MySociety’s fantastic MapIt API. All the data and code is on github.

Does it matter?

Obviously this isn’t a perfect way to rank parties. Although candidates stand in a particular ward they are elected to serve on the council for the entire borough. Many will live in neighbouring wards of the borough, have a reasonable idea of what local issues and be capable of doing a decent job. The results do does reflect my experience at hustings though – candidates who don’t live locally are often just parroting party policy and don’t address local concerns.

Plotting Air Quality Egg data using R

I recently got an Air Quality Egg. The Air Quality Egg is a open source hardware project to measure air quality hyper-locally. My egg is located on the balcony of my flat in Brixton, London. The Air Quality Egg device has sensors which read NO2, CO, humidity & temperature and posts the data to Cosm. You can view readings and simple graphs on the Cosm feed page.

Air Quality Egg on the balcony of my flat

Air Quality Egg on the balcony of my flat

Plotting sensor data using R

I wanted to see the trends in the data so I wrote a script in R to curl the data from the Cosm API and plot it using GGPlot.

Here is the script:

# grab an api key from cosm and put it here
api_key = 'YOUR_API_KEY'
# your feed id
feed_id = '106267'
csv_data = ""
start_date = as.POSIXct("2013/05/07","GMT")
end_date = as.POSIXct("2013/05/08","GMT")
while (start_date < end_date) {
start_date_as_str = format(start_date, format="%Y-%m-%dT%H:%M:00Z")
next_date = start_date + (3 * 60 * 60)
next_date_as_str = format(next_date, format="%Y-%m-%dT%H:%M:00Z")
cosm_url = paste("", feed_id, "/datastreams/NO2_00-04-a3-37-cc-cb_0.csv?start=", start_date_as_str, "&end=", next_date_as_str,"&interval=0", sep="")
csv_data_for_period = getURL(cosm_url, httpheader = c('X-ApiKey' = api_key) )
csv_data = paste(csv_data, csv_data_for_period, "\n")
start_date = next_date
data = read.table(textConnection(csv_data), sep = ",", col.names=c("at", "value"))
data$timestamp <- strptime(data$at, "%FT%T", tz = "UTC")
# strip out outliers
data = data[which(data$value < 1000),]
ggplot(data, aes(timestamp,value)) + geom_point() + geom_smooth() + xlab("Time") + ylab("NO2 PPB")
view raw gistfile1.r hosted with ❤ by GitHub

Here are some example graphs of NO2 over a single day and several days. (Note I don’t have the latest sensor updates so the readings may be a bit off)

Plot of NO2 for a single day

Plot of NO2 for a single day

Plot of NO2 for a 4 day period

Plot of NO2 for a 4 day period

The Internet of Things creates joy and happiness

I’m a member of Brixton Energy, a cooperative in South London that installs solar panels on social housing. The projects are crowd-funded by community members, with some of the profits used to support energy efficiency in the community. We are transparent about what we do and we want our investors to able to see the impact of their investments. One way we are doing this is by sharing how much electricity the panels are generating to anyone who is curious.

Opening up solar generation data

Unemotional data and graphs in solar log

Unemotional data and graphs in solar log

The solar generation data is logged to a website called solar log which came with the solar panel system. I wanted to integrate the data more closely with our website so I hacked together a really nasty script to scrape it from the solar log website and post the generation data to Cosm, the Internet of Things platform. In Cosm you can easily set up automated tweets based on changes to the data. I did just that and created a new twitter account @BES_Generation that tweets when electricity generation for the day exceeds 20, 50, 100, 150, 200 and 250kWh.

An unexpectedly emotional response

I set up the auto tweeting for my own use. First, to make sure that the data was posting successfully to Cosm and second, to get push notifications of how the solar panels were doing without having to visit the solar log website.

I was surprised by how cheerful and happy the tweets made me feel.

It might have been because it was March and winter was finally ending but the combination of sunshine, being involved in a cool environmental project and knowing my investment was doing well was a real buzz!

But then I was even more surprised that other people liked it too:



The real world causes real emotions

Real infrastructure in the real world - solar panels in Brixton

Real infrastructure in the real world – solar panels in Brixton

Usually data and websites themselves don’t produce an emotional response.

The Internet of Things seems different. It connects us to the physical world which is full of emotions.

In this case each tweet connected me to a community project that I am really proud to be part of and to the instinctive cheerfulness caused by a sunny day.

Brixton Hill’s not so local by-election candidates

Candidates are currently campaigning for the by-election to Lambeth council in the Brixton Hill ward where I live. Previously, council elections have just passed me by, but this one has caught my attention a lot (perhaps because its January and not much else is going on).

I have been following some of the candidates on twitter and UKIP candidate Elizabeth Eirwen Jones especially stood out. Her policies in support of cars seemed totally out of touch with the area I live in. It was like she was from another planet. After checking Lambeth’s council website which lists the addresses of each candidate it turns out she does live on another planet – planet Clapham.

Not so local candidates

Where Brixton Hill council candidates live (The brixton hill ward is in blue)

Where Brixton Hill council candidates live (The Brixton Hill ward is in blue)

In fact out of the 7 candidates only the two front runners Andrew James Child (Green party) and Martin Tiedemann (Labour) live in the ward. Three of the others live in Clapham and one lives in Vauxhall. But at least they live in Lambeth – one candidate Daniel Lambert (The Socialist Party) lives many miles away in Chislehurst.

One candidate lives in Chislehurst (bottom right)

One candidate lives in Chislehurst (bottom right)

Visualising the data

I built a little website to visualise the candidate addresses using the leaflet.js javascript library that runs on top of OpenStreetMap. I got borough and ward overlays from MySociety’s MapIt project. The code is on github.

How to export your data as a CSV from Solar Log

It is always a little bit sad when you have to write a instruction about how to use software. We are using Solar log to monitor our energy generation for Brixton Energy. Its really ace to see how much energy the solar panels are generating (check out our solar log page).

I read in the documentation that it was possible to export the data as a CSV, but it baffled me for half an hour on how to do os. I eventually figured it out and thought I would share how to do it so other can avoid the pain.

Exporting daily figures

  • Click the arrow beside Overview daily and select Overview monthly
  • Tick the values box on the right hand side of the page
  • Click the magnifying glass on the left hand side of the page
  • A popup window then appears with a table of values
  • On the bottom right of the table is the CSV link
  • You can use the arrows to either side of the magnifying glass to get data for the previous months

Note that the CSV is actually semi-colon (;) separated. You will need to use the import option in Excel to open it correctly. On one of the screens in the Excel wizard you can unselect commas as the separator and select semi-colons instead.