We will practice some visualisation techniques related to geolocation
To create a map in ggplot2
, we need to retrieve map data from the maps
package and draw it with geom_polygon()
. By default, the latitude and longitude will be drawn on a Cartesian coordinate plane, but we can use coord_map()
function to specify a projection.
Let’s start with drawing a world map.
# load tidyverse package
library(tidyverse)
# load maps package to get the map data
library(maps)
world <- map_data("world")
ggplot(world, aes(x = long, y = lat, group = group)) +
geom_polygon(fill = "gray90", colour = "gray30", size = 0.25) +
theme_void()
We can draw a specific country as follows:
# get map data for UK
uk <- map_data("world", region = "UK")
ggplot(uk, aes(x = long, y = lat, group = group)) +
geom_polygon(fill = "white", colour = "black") +
coord_map("mercator")
For this demo, we will use USArrests
datasets. For the details on the dataset, run ?USArrests
.
# using USArrests datasets
crimes <- data.frame(USArrests) %>%
mutate(state = tolower(rownames(USArrests)))
# get a map by states
states_map <- map_data("state")
# merge datasets together
crime_map <- states_map %>%
left_join(crimes, by = c("region" = "state")) %>%
arrange(group, order)
ggplot(data = crime_map, aes(x=long, y=lat, group = group, fill = Assault))+
geom_polygon(colour = "black")+
coord_map("polyconic")
Let’s try a different colour scheme that is perhaps more intuitive.
# Let's use colour palette from RColorBrewer pacakge
library(RColorBrewer)
ggplot(data = crime_map, aes(x=long, y=lat, group = group, fill = Assault))+
geom_polygon(colour = "black")+
coord_map("polyconic") +
scale_fill_gradientn(colors = brewer.pal(8,"Reds")) +
theme_void() # get rid of background
Instead of using the colour to encode the value, let’s draw circles and scale its area to encode the values.
# find a point per state to draw circles
summary <- crime_map %>%
group_by(region) %>%
summarise(mean_long = mean(long),
mean_lat = mean(lat),
Assault = first(Assault))
# first draw a background map, then draw the circles on top
ggplot()+
geom_polygon(data = crime_map, aes(x=long, y=lat, group = group), fill = "gray90", colour = "gray30", size = 0.25)+
theme_void() +
geom_point(data = summary, aes(x = mean_long, y = mean_lat, size = Assault), color = "red", alpha = 0.6) +
scale_size_area(max_size = 10)
display.brewer.all()
# ?USArrests
crimes <- data.frame(USArrests) %>%
mutate(state = tolower(rownames(USArrests)))
# get a map by states
states_map <- map_data("state")
# merge datasets together
crime_map <- states_map %>%
left_join(crimes, by = c("region" = "state")) %>%
arrange(group, order)
library(RColorBrewer)
# display.brewer.all()
ggplot(data = crime_map, aes(x=long, y=lat, group = group, fill = UrbanPop))+
geom_polygon(colour = "black")+
coord_map("polyconic") +
scale_fill_gradientn(colors = brewer.pal(8,"Greens")) +
theme_void() # get rid of background
# find a point per state to draw circles
summary <- crime_map %>%
group_by(region) %>%
summarise(mean_long = mean(long),
mean_lat = mean(lat),
UrbanPop = first(UrbanPop))
# first draw a background map, then draw the circles on top
ggplot()+
geom_polygon(data = crime_map, aes(x=long, y=lat, group = group), fill = "gray90", colour = "gray30", size = 0.25)+
theme_void() +
geom_point(data = summary, aes(x = mean_long, y = mean_lat, size = UrbanPop), color = "blue", alpha = 0.6) +
scale_size_area(max_size = 10)
# To get you started, here is how you can load the data. Change the file path accordingly to your working directory.
load(file = "wellbegin_uk_avg.RData")
load(file = "mapdata_uk.RData")
# merge datasets together
wellbeing_data_map <- mapdata %>%
left_join(wellbeing_data_avg, by = c("id" = "geography_id")) %>%
arrange(group, order)
# we create a dataset for happiness values and period 2019-20
library(dplyr)
wellbeing_happiness_map <- filter(wellbeing_data_map, measure == 'happiness')
wellbeing_happiness_map <- filter(wellbeing_happiness_map, time == '2019-20')
library(RColorBrewer)
# To draw the empty map. Modify the code below.
ggplot()+
geom_polygon(data = wellbeing_happiness_map, aes(x = long, y = lat, group = group, fill = score),
color ="white", size = 0.25)+
coord_equal() +
ggtitle("Happiness score UK") +
scale_fill_gradientn(colors = brewer.pal(8,"Blues")) +
theme_void()
#display.brewer.all()
# Load the data
load(file = "wellbegin_uk_avg.RData")
load(file = "mapdata_uk.RData")
# merge datasets together
wellbeing_data_map <- mapdata %>%
left_join(wellbeing_data_avg, by = c("id" = "geography_id")) %>%
arrange(group, order)
# we create a dataset for life-satisfaction values and period 2019-20
library(dplyr)
wellbeing_life_satisfaction_map <- filter(wellbeing_data_map, measure == 'life-satisfaction')
wellbeing_life_satisfaction_map <- filter(wellbeing_life_satisfaction_map, time == '2019-20')
library(RColorBrewer)
# Draw the map
ggplot()+
geom_polygon(data = wellbeing_life_satisfaction_map, aes(x = long, y = lat, group = group, fill = score),
color ="white", size = 0.25)+
ggtitle("Life satisfaction score UK") +
coord_equal() +
scale_fill_gradientn(colors = brewer.pal(8,"Blues")) +
theme_void()
Insight 1
The variance is low in the two different measures (happiness and life satisfaction mean) as we can see from the highest and lowest mean scores on the chart. This could add some difficulty in reading the map, as low variations might not be meaningful.
Insight 2
By looking at the happiness and life satisfaction visualisations we can see that the region of Northern Ireland has on average high mean scores. We can also detect that the colour becomes lighter around big cities as London and Manchester, which could be explained as city life could be more problematic and affect the feeling of its inhabitants.