An open API service indexing awesome lists of open source software.

https://github.com/mneedham/graphing-brexit


https://github.com/mneedham/graphing-brexit

Last synced: about 1 year ago
JSON representation

Awesome Lists containing this project

README

          

= Graphing Brexit

Along with many of my countrymen, I spent the night of 27th March 2019 watching UK MPs vote ‘No’ to a series of potential Brexit options, and then read analysis of how different individuals and parties had votes on various websites.
While being very interesting, all the analysis felt very tabular to me, and I was curious whether we could learn anything new by putting the data into a graph.

You can read more in https://medium.com/neo4j/graphing-brexit-bbe4314cf70[the blog post^] I wrote on this topic.

This repository contains the scripts, data, and queries that I reference in the post.

The blog post is based on data that I scraped from the Guardian website:

== Importing the Guardian data

Source: https://www.theguardian.com/uk-news/ng-interactive/2019/mar/27/how-did-your-mp-vote-in-the-indicative-votes

[source, cypher]
----
// Create one node per motion
LOAD CSV WITH HEADERS FROM "https://github.com/mneedham/graphing-brexit/raw/master/data/motions.csv" AS row
MERGE (m:Motion {id: toInteger(row.id)})
SET m.name = row.name;

// Create nodes for each MP and each party and connect them
LOAD CSV WITH HEADERS FROM "https://github.com/mneedham/graphing-brexit/raw/master/data/mps.csv" AS row
MERGE (person:Person {name: row.mp})
MERGE (party:Party {name: row.party})
MERGE (person)-[:MEMBER_OF]->(party);

// Create a relationship between each MP and each motion
LOAD CSV WITH HEADERS FROM "https://github.com/mneedham/graphing-brexit/raw/master/data/votes.csv" AS row
MATCH (person:Person {name: row.person})
MATCH (motion:Motion {id: toInteger(row.motionId)})
CALL apoc.create.relationship(person, row.vote, {}, motion)
YIELD rel
RETURN rel;
----

But then https://twitter.com/rbramley/status/1111535839811653632[Robin Bramley^] pointed out CommonsVotes, which has the data in CSV format.
It also has the data for the votes on Theresa May's various motions.

== Importing the CommonsVotes data

Source: https://commonsvotes.digiminster.com/

[source, cypher]
----
UNWIND [655,656,657,658,659,660,661,662] AS division
LOAD CSV FROM "https://github.com/mneedham/graphing-brexit/raw/master/data/commonsvotes/Division" + division + ".csv" AS row
WITH division, collect(row) AS rows
MERGE (motion:Motion {division: trim(split(rows[0][0], ":")[1]) })
SET motion.name = rows[2][0]
WITH motion, rows
UNWIND rows[7..] AS row
MERGE (person:Person {name: row[0]})
MERGE (party:Party {name: row[1]})
MERGE (constituency:Constituency {name: row[2]})
MERGE (person)-[:MEMBER_OF]->(party)
MERGE (person)-[:REPRESENTS]->(constituency)
WITH person, motion, CASE WHEN row[3] = "Aye" THEN "FOR" WHEN row[3] = "No" THEN "AGAINST" ELSE "DID_NOT_VOTE" END AS vote
CALL apoc.merge.relationship(person, vote, {}, {}, motion)
YIELD rel
RETURN count(*)
----

== Importing the House of Commons Library data

Source: https://commonslibrary.parliament.uk/parliament-and-elections/elections-elections/brexit-votes-by-constituency/

[source, cypher]
----
LOAD CSV WITH HEADERS FROM "https://github.com/mneedham/graphing-brexit/raw/master/data/euref.csv" AS row
MATCH (c:Constituency) WHERE toLower(c.name) = toLower(row.Constituency)
SET c.leave = toFloat(apoc.text.replace(row["TO USE"], "%",""))
----

== Mapping of ids to short names

. Mr Clarke's motion J (Customs union)
. Margaret Beckett's motion M (Confirmatory public vote)
. Jeremy Corbyn's motion K (Labour's alternative plan)
. Nick Boles's motion D (Common market 2.0)
. Joanna Cherry's motion L (Revocation to avoid no deal)
. Mr Baron's motion B (No deal)
. Mr Fysh's motion O (Contingent preferential arrangements)
. George Eustice's motion H (EFTA and EEA)

== Other ideas

* [ ] https://twitter.com/chriseyre2000/status/1111908414521638912[Infer new political groupings^]
* [ ] Add Theresa May's motions
* [ ] Changes in how people vote in the Theresa May motions
* [ ] https://twitter.com/EastlondonDev/status/1111651874413969409[Cosine distance between motions and use that to try a ranking^]
* [ ] https://twitter.com/davidbarton_/status/1111523034459000832[Similarity of motions^]
* [ ] https://twitter.com/fluffymaccoy/status/1111542849751998464[Individual stance vs party affiliation^]
* [ ] https://twitter.com/fluffymaccoy/status/1111542518280261632[Constituencies banded into leave/remain and strong/weak^]
* [ ] https://twitter.com/mesirii/status/1111513552081293312[Clusters of MPs^]
* [ ] Full graph with bloom to show clusters
* [ ] Top k similarity graph
* [ ] Geocode MPs and put them on a brexit map