Thursday, February 22, 2018

Using R to View the 2016 Italian Referendum Results

Overview | Code | Output

Three maps showing the elections of the 2016 Italian Referendum results. Left: Choropleth map. Center:  Bubble plot. Right: Worldwide bubble plot.


We are currently working our way through the Microsoft Professional Program in Data Science. There has been a lot of opportunity to work with the R programming language and software environment commonly used in statistical computing. In particular, the course Programming with R for Data Science gives students the opportunity to experiment with combining static maps (e.g. Google Maps) and data overlay overlays. In honor of the upcoming election in Italy, we thought it would be interesting to look at some recent Italian election statistics using R. The code plots the 2016 Italian Referendum results for inside Italy by region and worldwide. The data for this post comes from the Wikipedia article Italian constitutional referendum, 2016. Any errors transcribing the data are our own.


You should be able to paste the code below directly onto the command line of your R environment. Here is the code on Github. See the notes below for more information.


regionsEN=c("Abruzzo", "Aosta Valley", "Apulia", "Basilicata", "Calabria",
"Campania", "Emilia-Romagna", "Friuli-Venezia Giulia", "Lazio",
"Liguria", "Lombardy", "Marche", "Molise", "Piedmont", "Sardinia",
"Sicily", "Trentino-South Tyrol", "Tuscany", "Umbria", "Veneto",
"Italy", "Europe", "'South America'", "'North America'", "Asia")

regionsIT=c("Abruzzo","Valle d\'Aosta", "Puglia", "Basilicata","Calabria",
"Campania", "Emilia-Romagna", "Friuli-Venezia Giulia", "Lazio",
"Liguria", "Lombardia", "Marche", "Molise", "Piemonte", "Sardegna",
"Sicilia", "Trentino-Alto Adige", "Toscana", "Umbria","Veneto",
"Italia", "Europa", "America meridionale", "American settentrionale e centrale",
"Africa, Asia, Oceania, Antartide")


electorate=c(1052049, 99735, 3280745, 467000, 1553741,
4566905, 3326910, 952493, 4402145,
1241618, 7480375, 1189180, 256600, 3396378, 1375845,
4031871, 792503, 2854162, 675610, 3725399,
46720943, 2166037, 1291065, 374987, 220252)

percentNo=c(64.4, 56.8, 67.2, 65.9, 67.0,
68.5, 49.6, 61.0, 63.3,
60.1, 55.5, 55.0, 60.8, 56.5, 72.2,
71.6, 46.1, 47.5, 51.2, 61.9,
60.0, 37.6, 28.1, 37.8, 40.3)

referendum=c(rep("No",6),"Yes",rep("No",9),"Yes", "Yes", rep("No", 3), rep("Yes", 4)) <- data.frame(regionsEN, regionsIT, electorate, referendum, isRegion, percentNo)$regionsEN <- as.character($regionsEN)
latlon <- geocode($regionsEN)<-cbind(,latlon)<-subset(,isRegion==TRUE)<-subset(,isRegion==FALSE)
title <- "Referendum 2016 Results"

# generate Italy map
p <- ggmap(get_map(location="Italy",zoom=6), extent="panel")
p <- p + geom_point(aes(x=lon, y=lat),, 
colour=ifelse($referendum == "No",'red','green'),
p <- p + labs(title=paste(title, "by Region"))

# general Italy choropleth map
gp <- list(guide.label="Percent\nNo\nVote", title="2016 Referendum Results by Region", 
low="green", high="red")
mapIT(percentNo, regionsIT,,  graphPar=gp)

# generate world map
q <- openproj(openmap(c(70,-145), c(-70,145), zoom=1)) 
q <- autoplot(q) + geom_point(aes(x=lon, y=lat),, 
col=ifelse($referendum == "No",'red','green'),
alpha=0.4, size=log($electorate))
q <- q + labs(x="lon", y="lat", title=paste(title,"Worldwide")) 


  • For an  R environment, we use both Microsoft R Client and RStudio, but prefer the latter slightly.
  • We made some minor tweaks to the region and constituencies (outside of Italy) to make geocoding easier and place the bubble for a given constituency in a position on the map that makes sense. In particular, we simplified 'North and Central America' to 'North America' and 'Africa, Asia, Oceania, Antarctica' to 'Asia'. 
  • The get_map()function can't produce world map as described in this Stack Overflow post, so we found other ways to create a world map with the rworldmap and openstreetmap package. We use the openstreetmap to create a world view and rworldmap along with mapIT to to create a choropleth map of Italy. 
  • The mapIT package is discussed in Building a choropleth map of Italy using mapIT. Note in the code above that there are two listings of the Italian regions and constituencies, regionsEN in English and regionsIT in Italian. regionsEN was used with ggmap::geocode() and regionsIT was used with mapIT
  • You may see over-query-limit warnings as described in the Stack Overflow post. We saw this in happen in the course of running the code multiple times.


The code generates three plots as show at the head of this post.

The referendum was soundly defeated. Inside Italy, 60% voted against it. Only three regions approved it: Emilia-Romagna, Trentino-Alto Adige and Tuscany. The bubble plot shows the size of of the electorate (size of bubble) and their final vote (red for no and green for yes). The choropleth plot shows more clearly that the strongest no vote was more prevalent in the south of Italy.

About 10% of Italians are live outside of Italy and are broken into for constituencies: Europe, South America, North and Central America, and Africa / Asia / Oceania / Antarctica. Each of these constituencies voted for the referendum as can be seen in the worldwide bubble plot. In the worldwide plot, the logarithm of the number of votes is plotted. It's not a particularly compelling visualization because the size of the green bubbles (all constituencies outside of Italy) and the red bubble (Italy) could lead a viewer to incorrectly conclude the referendum passed overall.

For more on voting in Italy, in particular how overseas voting works, see The Italian March 2018 Election for Overseas Italians – Observations and Vocabulary Lesson.

No comments:

Post a Comment

All comments go through a moderation process. Even though it may not look like the comment was accepted, it probably was. Check back in a day if you asked a question. Thanks!