On the eve of triggering Article 50, I think it’s semi-fitting to revisit the Brexit results.

What’s the topic?

The 2016 Brexit catastrophy (a.k.a. United Kingdom European Union membership referendum, 2016), specifically the visualisation of the results on a map, with each area (Local Authority in this case) proportioned by the number of votes, in the hope that it could capture the variety of sentiment on the topic across the country. The use of Cartogram should be an obvious choice in distorting the map areas, and while there have been plenty visualisation of such kind for General Elections, it has not been done for the Brexit.

Is there anything new I’m getting?

After so much has been done on visualising the voting result, there doesn’t seem to be a map that represent the split based on the number of votes for each region. I thought I’d combine the following to create just that with R:

What are the benefits, if any?

Get down to the business

The votes data

The data source is The Electoral Commssion and the CSV can be downloaded directly from here.

So there are 382 Local Authorities. Let’s get the appropriate shapefile, and check out what data is already attached:

The hexagon shapefile

Let’s plot it against an actual map to get a sense of it. To do that let’s project it to WGS84 (EPSG:4326) measured in degrees of latitude / longitude, which also allows to set up the bouding box easier.

Note: using ggplot to overlay polygons on a map requires turning the shapefile into a data frame by using broom::tidy(). After running the function if you encounter this error Error: isTRUE(gpclibPermitStatus()) is not TRUE on Windows, make sure Rtools is installed, then install package gpclib using install.packages('gpclib', type = 'source'). To verify everything is fine, run gpclibPermitStatus() and gpclibPermit(), if both return True then you are all set.

So the hexagon map is roughly based on the actual coordicates of the features.

But wait, the Local Authority shapefile has a flaw - it is missing Northern Ireland and Gibraltar, confirmed by comparing the names from the CSV and the shapefile (The Vale of Glamorgan also has different names in the two files, let’s deal with that later)

Let’s create them!

Create features (polygons) in a shapefile

Manipulating the shapefile can be a daunting task, as it has multiple layers of nested elements like this:

And inside the @ polygons element are all the features (points, lines and polygons), for each of them there is this:

Now that the structure is clearly laid out, this is what we need to do

  1. create a new polygon by copying from one of the existing ones
  2. work out the coordinates for the new polygon
  3. change the coordinates of the polygon
  4. append the polygon with the existing ones
  5. reconstruct the @ polygons list
  6. recreate the shapefiles with the polygons list and other values from the original shapefile

The plan is to create NI and GI features by copying one of the polygons near by, shift it to an appropriate location, and update the attributes and data to reflect NI and GI respectively. So I decided using the British National Grid projection (EPSG:27700), as measured in meters, would be a better choice, as the shift can be explicit and more understandable.

Barrow-in-Furness is a good choice as a neighbouring polygon. NI is esitmated to be 100,000 meters to the west, and GI is 600,000 meters to the south of NI. (the step numbers in the code correspond to the above five steps)

Let’s check that the polygons have indeed been created:

Much better. Even though they do not exactly fall inside the geospatial boundaries of the actual areas, it’s good enough for the hexagon map.

Before moving on, let’s fix the little issue with The Vale of Glamorgan:

Voting results on a hexagon map

Prior to this point we have been working with the voting data and the shapefile separately, now it’s time to combine the voting data and the map:

Then we can plot the hexagon:

As one would expect, the voting results are clear (direction-wise) for each Local Authority, and we are indeed seeing London the Remain capital and the surrounding areas being more prominently represented, but the map is still mis-representing the relative valid votes of each area, i.e. regardless of the number of valid votes, all areas are of the same size.

Let’s try rescaling the map using the Valid_Votes inside the votes data.

There are various options for creating a cartogram map, notably Rcartogram and getcartr packages have been used together (e.g. Michael Höhle’s nice post). The downside of those is that the installation process can be complicated (see this Stack Overflow answer for a complete process). for a simple solution the cartogram package on CRAN is a good alternative:

This makes slightly more sense, but there are still a couple issues:

The proportion of Leave and Remain varies across regions wildly:
Note, for Northern Ireland there is only one data point (@ 55.8%), hence the invisible verticle line in the density graph.

Therefore we must not lose the information on the map.

Further more, aren’t you just dying to work out which area is which?

Let’s get straight down to leaflet to address all of the above.

Plotting cartogram with leaflet

Before plotting the map we need to take care of a few things:

More dramatic scaling

The above cartogram looks fine, it probably represent the valide votes fairly accurately. But for aesthetic purposes, I think a more dramatic scaling would be more interesting, this means the difference of polygons are exaggerated and some areas are over shaddowing others in size, but that would make the visualisation more telling, and easier to grab attention, which is a major point of data visualisation. So instead of using Valid_Votes we use the square of it.

Information tag

Taking advantage of Javascript we can include much information dynamically, e.g. showing the votes when the mouse cursor hovers on the polygons. These need to be created as separate HTML tags.

Colouring for votes percentage

There is a wide range of votes percentage (% of Remain from 24% to 96%), This should be differentiated by colours. The last thing we need to take care off is a small tweak on the scaler for Gibraltar. Gibraltar being a British overseas territory (with a population of just over 30,000, located at the bottom of Spain) naturally voted overwhelmingly Remain (yes, that one with 96%). Allowing the outlier to be part of the colour palette would push everything close hence showing less disguishable colours, and for this reason, we are going to make the outlier value the same as the second highest (Lamberth at 79%, and by now you probably know where I stand on the McCandless vs. Tufte debate).

That is not too bad. Why don’t we plot a ggplotly version

There we have it. All the source code is in my repo. Feel free to comment / pick bones.