Data Visualisation of European Parliament Data using R
In recent years the scope and importance of the European Parliament to democracy across the member states has increased markedly. With this increase in it’s relevance, a noticeable increase in access to data has abounded, but what does the data mean? And more importantly, what can it tell us? In this short blog, I’ll play around with some of this data in R, in order to demonstrate not only some interesting aspects of the data, but also demonstrate how to simply create interactive and clear visualisations of data in R. While I will provide an insight for those who are interested in exploring some of the policy dimensions at play in dealing with European Parliament Data, and more particularly the voting records of the European Parliament. All of this data is sourced from the Parltrack website, and a full list of data sources is available here. This data looks at the period 2015 – 2019 when there were 751 MEPS, before the exit of the UK led to a reduction to 705
Let’s start by reading in some of the core packages I will use:
library(ggplot2) library(ggplotify) library(plotly) library(viridis) library(highcharter) library(readxl) library(dplyr) library(gganimate) library(gapminder) library(treemapify) library(esquisse)
Then of course we will proceed to read in the data which we will use, this data is available via the link above.
European_Parliament_MAIN_data <- read_excel("European Parliament MAIN data.xlsx")
Now, because we’re not going to be doing much in the way of modifying the data and instead will just focus on ways to visualise the data, we won’t need to do too much work on the data. For the visualisations I will use both ggplot and the related package of ggplotly, which allows for a more interesting, and oftentimes useful interactive element to visualisations. For our first visualisation, we will look at where support for bills is strongest, across different thematic areas, and help shed a little more light by looking also at the ‘procedure’ used on the bills.
mepsuppproc <- ggplot() + geom_point(data=European_Parliament_MAIN_data, aes(support, policyarea, color=procedure)) + labs(title = " Levels of MEP Support by Bill", x="Support for Bill", y = "Policy Area") ggplotly(mepsuppproc)
The visualisation above should now be interactive, allowing you to hover over and engage with specific votes, however it’s explanatory power is generally limited, apart from the observation that more bills seem to have positive, rather than negative levels of support, indicating perhaps more bills pass.
Lets now turn our attention to whether turnout effects whether a bill passes, which we do via a similar visualisation approach as laid out above.
turnvote <- ggplot() + geom_point(data=European_Parliament_MAIN_data, aes(voters, finalv, color=policyarea)) + labs(title = "Voter turnout by vote result", x="Voters for Bill", y = "Bill passed?") a <- ggplotly(turnvote) hide_legend(a)
What we can see in the above is generally that when a bill fails to pass, it’s likely a contenious issue as it leads to a large turnout of MEPS to cast their votes. While those bills which pass can do so with a relatively small turnout of MEPS to cast their vote.
We can see below how the presence of quora in the European Parliament are likely driving this turnout, as many bills veer quite close to the quora on particular bills.
responsive <- ggplot() + geom_point(data=European_Parliament_MAIN_data, aes(require, voters, color=policyarea)) + labs(title = "Voter turnout by number of votes required on a bill", x="Voters required", y = "Voters") b <- ggplotly(responsive) hide_legend(b)
Turning from this, we can now focus on a novelty contained within the dataset – level of rebellion – which looks at deviation from parliamentary grouping, and here we want to look at whether the number of MEPs who turnout to vote, has any real effect on the level of rebellion in the European Parliament.
mepreb <- ggplot() + geom_point(data=European_Parliament_MAIN_data, aes(voters, levreb, color=policyarea)) + labs(title = "MEP Support by MEP Turnout", x="Voters for Bill", y = "Level of Rebellion") c <- ggplotly(mepreb) hide_legend(c)
Here we can see that with the exception of some low-ish turnout bills where level of rebellion is quite high, that in general the pattern of rebellion from parliamentary grouping, is generally unconnected from vote turnout for a bill.
Next we will look at whether support instead differs by the type of vote undertaken in the European Parliament, and see if any patterns emerge.
policyagen <- ggplot() + geom_point(data=European_Parliament_MAIN_data, aes(support, typeofvote, color=policyarea)) + labs(title = "Policy Agenda Support by Vote Type", x="Total Support", y = "Type of Vote") l <- ggplotly(policyagen) hide_legend(l)
The pattern appears to be quite interesting, for example a ‘Joint motion for resolution’ appears to enjoy widespread support, whereas a ‘motion for resolution’ appears to experience considerably more pushback in the form of reduced total support.
The breakdown of this across thematic policy areas is contained below and provides an insight into what these means in substantive policy terms.
policyagenrev <- ggplot() + geom_point(data=European_Parliament_MAIN_data, aes(support, policyarea, color=typeofvote)) + labs(title = "Policy Agenda Support by Vote Type", x="Total Support", y = "Type of Vote") l <- ggplotly(policyagenrev) hide_legend(l)
Here we can see that some of the more contentious bills brought to the European Parliament are typically either ‘motion for resolutions’ which are focused on areas such as International Trade, Development and Foreign and Security Policy. While it appears that ‘draft legislative resolutions’ which are focused on issues such as Transport & Tourism and Civil liberties, justice and home affairs are likewise contentious and likely to receive significant negative levels of support.
For the final visualisation, I play around a little with the ability in ggplot and plotly to creative short gif style animations, and show all the bills which passed with their respective support for the bill on the x axis and opposition to the bill on the y axis.
g <- ggplot(European_Parliament_MAIN_data, aes(forbill, againstbill, frame = date, color=passed)) + geom_point() + geom_smooth(aes(color=passed), show.legend = T) + labs(title = " MEP Voting Records and Bill Success", x="Voters for Bill", y = "Voters against bill") + scale_x_log10() # convert to log scale w <- ggplotly(g) hide_legend(w)
European Parliament Data continued.
I hope that you enjoyed this relatively light introduction into some interesting things which can be done with ggplot and plotly, and found the European Parliament Data mildly interesting and my simple analysis of the visualisations useful to guide you. Of course, I am not a scholar of the European Parliament, and my motivation was more to play around with some parliamentary visualisation approaches.
As always, feel free to contact me or leave a comment below.