https://github.com/mneedham/graphing-brexit
https://github.com/mneedham/graphing-brexit
Last synced: about 1 year ago
JSON representation
- Host: GitHub
- URL: https://github.com/mneedham/graphing-brexit
- Owner: mneedham
- Created: 2019-03-28T21:38:07.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2019-10-18T15:33:50.000Z (over 6 years ago)
- Last Synced: 2025-02-14T13:50:23.866Z (over 1 year ago)
- Language: HTML
- Size: 334 KB
- Stars: 7
- Watchers: 3
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.adoc
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