tmapThis is especially true when presenting spacial data. A well presented map can often communicate more effectively than data tables.
The Australian Marriage Law Postal Survey was an integral step towards legislating marriage equality in Australia.
This vignette will be using data from the ABS and the tmap library, to visualise the Australian Marriage Law Postal Vote response of Australian Federal Electoral Divisions. The focus of the vignette will be on presenting different maps and layers using the tmap package. Hence only a quick overview of the importing, cleaning and intial plotting of the dataset will be provided below.
library(tidyverse) #to cleaning data
library(rgdal) #read shapefile containing geospatial data
library(tmap) #create thematic maps
The Australian Marriage Law Postal Survey Response data at a federal electorate division (FED) level can be found at http://stat.data.abs.gov.au/#.
Note: Using an API key for the SDMX did not import the federal electorate names (required for joining the data sets further along), hence to import the data set, I downloaded a csv file to load.
#load voting data
aus_vote_raw <- read_csv("AMLPS_RESP_2017_14082019213322035.csv")
glimpse(aus_vote_raw)
## Observations: 2,226
## Variables: 13
## $ RESPONSE_CAT <chr> "EP_TOT", "EP_CLR", "EP_NCLR", "E...
## $ Response <chr> "Eligible Participant - Total", "...
## $ MEASURE <dbl> 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, ...
## $ Measure <chr> "Number (No.)", "Number (No.)", "...
## $ REGIONTYPE <chr> "AUS", "AUS", "AUS", "AUS", "AUS"...
## $ `Geography Level` <chr> "Australia", "Australia", "Austra...
## $ AEC_FED_2017 <chr> "0", "0", "0", "0", "0", "0", "0"...
## $ `Federal Electoral Division` <chr> "Australia", "Australia", "Austra...
## $ TIME <dbl> 2017, 2017, 2017, 2017, 2017, 201...
## $ Year <dbl> 2017, 2017, 2017, 2017, 2017, 201...
## $ Value <dbl> 16006180.0, 12691234.0, 36686.0, ...
## $ `Flag Codes` <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N...
## $ Flags <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N...
A shapefile is a geospatial vector dataform that stores the geometric location and attributes of geographical features.
The Australian Electoral Commission stores GIS files on Federal Electoral Boundaries at https://www.aec.gov.au/Electorates/gis/gis_datadownload.htm
#download and unzip the shapefile
download.file("https://www.aec.gov.au/Electorates/gis/files/national-esri-fe2019.zip", destfile = "Electorate_Boundaries.zip")
unzip("Electorate_Boundaries.zip")
#read the shapefile using the `rgdal` library
aus_electorate_map <- readOGR(dsn = "COM_ELB_region.shp")
## OGR data source with driver: ESRI Shapefile
## Source: "C:\Users\pfspl\Documents\R\STDS\AT1 - Vignette\COM_ELB_region.shp", layer: "COM_ELB_region"
## with 151 features
## It has 9 fields
## Integer64 fields read as strings: Numccds Actual Projected Total_Popu Australian
#to easily read the data within the shapefile, convert the data section into a dataframe
aus_electorate_df <- as.data.frame(aus_electorate_map)
glimpse(aus_electorate_df)
## Observations: 151
## Variables: 9
## $ Elect_div <fct> Bean, Canberra, Fenner, Lingiari, Solomon, Blair, B...
## $ State <fct> ACT, ACT, ACT, NT, NT, QLD, QLD, QLD, QLD, QLD, QLD...
## $ Numccds <fct> 351, 311, 274, 327, 223, 390, 352, 345, 364, 398, 4...
## $ Actual <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ Projected <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ Total_Popu <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ Australian <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ Area_SqKm <dbl> 1.913970e+03, 3.122631e+02, 2.382121e+02, 1.348158e...
## $ Sortname <fct> Bean, Canberra, Fenner, Lingiari, Solomon, BLAIR, B...
#cleaning data
aus_vote_clean <- aus_vote_raw %>%
select(-TIME, -Year, -`Flag Codes`,-Flags,-`Geography Level`,-Response) %>% #remove same/blank values
spread(key = "RESPONSE_CAT", value = "Value") %>% #convert from long to wide data
filter(MEASURE == 2)%>% #I have chosen to visualise % of votes in each FED rather than no. of votes
dplyr::rename("Elect_div" = "Federal Electoral Division") #renamed to facilitate the joining of datasets
glimpse(aus_vote_clean)
## Observations: 159
## Variables: 12
## $ MEASURE <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2...
## $ Measure <chr> "Percentage (%)", "Percentage (%)", "Percentage (...
## $ REGIONTYPE <chr> "AUS", "FED", "FED", "FED", "FED", "FED", "FED", ...
## $ AEC_FED_2017 <chr> "0", "ADEL", "ASTO", "BALL", "BANK", "BARK", "BAR...
## $ Elect_div <chr> "Australia", "Adelaide", "Aston", "Ballarat", "Ba...
## $ EP_CLR <dbl> 79.3, 81.2, 81.4, 81.4, 79.9, 76.8, 77.8, 79.0, 8...
## $ EP_NCLR <dbl> 0.2, 0.2, 0.2, 0.3, 0.2, 0.2, 0.2, 0.2, 0.3, 0.3,...
## $ EP_NR <dbl> 20.5, 18.6, 18.4, 18.3, 19.9, 23.0, 22.0, 20.8, 1...
## $ EP_TOT <dbl> 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,...
## $ RESPCLR_N <dbl> 38.4, 29.9, 38.0, 29.5, 55.1, 47.7, 56.4, 38.3, 2...
## $ RESPCLR_TOT <dbl> 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,...
## $ RESPCLR_Y <dbl> 61.6, 70.1, 62.0, 70.5, 44.9, 52.3, 43.6, 61.7, 7...
Both the vote data and the map shapefile include a Federal Electoral Division attribute, hence the two data sets will be joined via this attribute.
#join the vote data to the electorate map by column Elect_div using the join function in diplyr
aus_electorate_map@data <- left_join(aus_electorate_map@data,aus_vote_clean,by = "Elect_div")
head(aus_electorate_map)
## class : SpatialPolygonsDataFrame
## features : 6
## extent : 96.81694, 167.998, -35.92076, -10.41236 (xmin, xmax, ymin, ymax)
## crs : +proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs
## variables : 20
## names : Elect_div, State, Numccds, Actual, Projected, Total_Popu, Australian, Area_SqKm, Sortname, MEASURE, Measure, REGIONTYPE, AEC_FED_2017, EP_CLR, EP_NCLR, ...
## min values : Bean, ACT, 223, 0, 0, 0, 0, 190.61, Bean, 2, Percentage (%), FED, BLAI, 50, 0.2, ...
## max values : Solomon, QLD, 390, 0, 0, 0, 0, 1348157.94, Solomon, 2, Percentage (%), FED, SOLO, 83.1, 0.2, ...
Using the quick thematic map (qtm) function in tmap, we can create a quick choropleth map, using colour to show the % of the population voting Yes.
qtm(aus_electorate_map, fill = "RESPCLR_Y")
Note: the Yes % refers to number of yes votes relative to the total number of clear responses received from the survey.
tmap PlottingThematic maps are designed to empahsise a topic or theme, using geographic information as reference points.
The tmap package allows for easy and flexible creation of thematic maps.
There are two plotting modes in tmap:"plot" - to create static maps and "view" - to create interactive maps. We will focus on creating static maps below.
tmapThere are a multitude of adjustments you can make to the base map. ?'tmap-element' will provide the complete list of elements for each layer and outline their functions.
The code below is just an example of many formatting changes you can make to the map.
tmap_mode("plot") #static map
## tmap mode set to plotting
tm_shape(aus_electorate_map)+
tm_polygons("RESPCLR_Y", #determines fill
title = "Yes %", #legend title
border.col = "saddlebrown")+ #border colour of polygons
#general level layout attributes
tm_layout(title = "Australian Marriage Law
\nPostal Vote", #title inside the map border (\n for new line)
title.color = "midnightblue",
bg.color = ("whitesmoke"))+ #background map colour
#format the map legend
tm_legend(legend.title.color = "white",
legend.title.size = 1.2,
legend.text.color = "white",
legend.text.size = .8,
legend.width = 2, #adjust width of legend for text size
legend.position = c("right","top"),
legend.bg.color = "slategray",
legend.bg.alpha = 0.8)+ #transparency of legend background colour
#create a compass on the map
tm_compass(north = 0, #direction of north compass
type = "8star",
size = 4, #size of the compass
position = c("right","bottom"),
color.dark = "dimgray", #colour of shaded parts of compass
text.color = "dimgray")
tmapThe tmap package also allows to facet maps by multiple variables or by splitting the spatial data. This can be both a static and interactive map!
Below is an example of a static facet by multiple variables on the state of Tasmania.
Note: A limit of 4 facets in an interactive map
tmap_mode("plot") #static map
## tmap mode set to plotting
aus_TAS_electoral_map <- aus_electorate_map[aus_electorate_map@data$State == "TAS",] #Tasmanian dataset
tm_shape(aus_TAS_electoral_map)+
tm_polygons(c("RESPCLR_Y","EP_CLR"), #variables to facet by
palette= list("Blues","Purples"), #allows different palettes for each variable
title = c("% Responded","% Yes"))+ #legend title for each facet
tm_layout(main.title = "Australian Marriage Law Postal Vote - Tasmania", #title above the map
main.title.position = "center",
main.title.color = "darkblue",
panel.show = TRUE, #show panels at the top of each facet
panel.labels = c("% of clear responses","% voted yes"),
panel.label.color = "white",
panel.label.bg.color = "midnightblue")+
tm_legend(legend.bg.color = "dimgray",
legend.text.color = "white",
legend.title.color = "white")
Note: The aus_electorate_map already had the voting data joined to it, so filtering on just the state of Tasmania will include the voting data for the state.
tmaptmap also allows you to create maps with multiple layers from different data sources. As an example, the map below includes two additional data sets from tmaps.
data(metro) #adding an additional dataset from tmap to show layering
data(rivers) #adding an additional dataset from tmap to show layering
tmap_mode("plot")
## tmap mode set to plotting
tm_shape(aus_electorate_map)+
tm_polygons("RESPCLR_Y",
title = "Yes %",
alpha = 0.85)+ #transparency of the polygon
tm_shape(metro)+ #add another layer to the interactive map
tm_bubbles(size = "pop2020", #maps the points on the second layer
col = "deeppink", #fill colour of the shapes
scale = 5, #magnifies the size of the points
alpha = 0.7,
title.size = "2020 Population", # rename legend of population
legend.size.is.portrait = TRUE)+ #shows population legend stacked
tm_shape (rivers)+ #add another layer to the interactive map
tm_lines("blue")+ #line colour
tm_legend(legend.position = c("left","bottom"))
The tmap package is great for visualising spatial data and creating thematic plots, both static and interactive.