How to create advanced static maps

Advanced static maps in R

Anne Sophie Gill https://www.skemagloballab.io/gillAnneSophie.html (SKEMA Global Lab in AI)https://skemagloballab.io , Thierry Warin https://www.nuance-r.com/principalInvestigator.html (SKEMA Business School (Raleigh, NC))https://www.skemagloballab.io
03-09-2020

This blog post will show you how to create an advanced static map with a legend in the SKEMA Quantum Studio (Warin 2019).

How to create a static map with a legend

Step 1 : Load following libraries


library(maps)
library(ggplot2)
library(dplyr)
library(readr)
library(rgdal)
library(sp)
library(stringr)
library(tidyverse)
library(broom)

Step 2 : Extract Data


# Data Frame containing info on NYC 2018 murders per borough
NYC2018murders <- read.csv("NYC2018murders.csv", header = TRUE)
head(NYC2018murders)

  borough  weapon record
1   BRONX HANDGUN      1
2   BRONX HANDGUN      1
3   BRONX HANDGUN      1
4   BRONX HANDGUN      1
5   BRONX HANDGUN      1
6   BRONX HANDGUN      1

# NYC boroughs Shapefile
# * remember, the .zip file must contain at least the .shp, .shx, .dbf, and .prj files 
# components of the shapefile for your Shapefile to work properly in SKEMA Quantum Studio
Map1 <- readOGR("nycB.shp")

OGR data source with driver: ESRI Shapefile 
Source: "/home/gilla/mondo/skemalab/blog/_posts/2020-03-09-advancedstaticmap/nycB.shp", layer: "nycB"
with 5 features
It has 4 fields

# Get "Map1" into tidy format using the tidy() function of the "broom" package.
Map2 <- tidy(Map1)
head(Map2)

# A tibble: 6 x 7
      long     lat order hole  piece group id   
     <dbl>   <dbl> <int> <lgl> <chr> <chr> <chr>
1 1021632. 267934.     1 FALSE 1     0.1   0    
2 1022109. 267751.     2 FALSE 1     0.1   0    
3 1022178. 267762.     3 FALSE 1     0.1   0    
4 1022216. 267734.     4 FALSE 1     0.1   0    
5 1022273. 267697.     5 FALSE 1     0.1   0    
6 1022332. 267664.     6 FALSE 1     0.1   0    

# Add @data back to our Map2 object
Map1$id <- row.names(Map1)

Map2 <- left_join(Map2, Map1@data)
head(Map2)

# A tibble: 6 x 11
    long    lat order hole  piece group id    BoroCode BoroName
   <dbl>  <dbl> <int> <lgl> <chr> <chr> <chr>    <int> <fct>   
1 1.02e6 2.68e5     1 FALSE 1     0.1   0            2 Bronx   
2 1.02e6 2.68e5     2 FALSE 1     0.1   0            2 Bronx   
3 1.02e6 2.68e5     3 FALSE 1     0.1   0            2 Bronx   
4 1.02e6 2.68e5     4 FALSE 1     0.1   0            2 Bronx   
5 1.02e6 2.68e5     5 FALSE 1     0.1   0            2 Bronx   
6 1.02e6 2.68e5     6 FALSE 1     0.1   0            2 Bronx   
# … with 2 more variables: Shape_Leng <dbl>, Shape_Area <dbl>

Step 3: Data wrangling


# Make sure your data is in the appropriate format
NYC2018murders$borough <- as.character(NYC2018murders$borough)
NYC2018murders$record <- as.character(NYC2018murders$record)
NYC2018murders$weapon <- as.character(NYC2018murders$weapon)
NYC2018murders$record <- as.numeric(NYC2018murders$record)

# Use aggregate function to get the total sum of murders per borough
NYC2018murdersAgg <- aggregate(record~ borough, data = NYC2018murders, sum)  

# Make sure the boroughs are written exactly the same in all the data frames
Map2$BoroName <- str_to_upper(Map2$BoroName)
Map2$BoroName <- as.character(Map2$BoroName)

# rename the column "BoroName" and call it "borough"
names(Map2)[names(Map2) == "BoroName"] <- "borough"

# Join the 2 data frames
FINAL <- left_join(Map2, NYC2018murdersAgg, by = "borough")
head(FINAL)

# A tibble: 6 x 12
    long    lat order hole  piece group id    BoroCode borough
   <dbl>  <dbl> <int> <lgl> <chr> <chr> <chr>    <int> <chr>  
1 1.02e6 2.68e5     1 FALSE 1     0.1   0            2 BRONX  
2 1.02e6 2.68e5     2 FALSE 1     0.1   0            2 BRONX  
3 1.02e6 2.68e5     3 FALSE 1     0.1   0            2 BRONX  
4 1.02e6 2.68e5     4 FALSE 1     0.1   0            2 BRONX  
5 1.02e6 2.68e5     5 FALSE 1     0.1   0            2 BRONX  
6 1.02e6 2.68e5     6 FALSE 1     0.1   0            2 BRONX  
# … with 3 more variables: Shape_Leng <dbl>, Shape_Area <dbl>,
#   record <dbl>

Step 4 : Create the map


# Create labels
Label <- FINAL %>%
  group_by(borough) %>%
  summarise(label_long = mean(range(long)), label_lat = mean(range(lat)))

# Customize your map
map1 <- ggplot(FINAL, aes(long, lat, group = group))+
        geom_polygon(aes(fill = record), color = "white", show.legend = FALSE)+
        scale_fill_gradient(low = "green", high = "yellow") +
        coord_equal() +
        theme_void() + 
        labs(title = "New York City Boroughs",
        caption = "Source: SKEMA Quantum Studio") +
        geom_text(data = Label, 
            mapping = aes(x = label_long, y = label_lat, label = borough, group = NA),
            cex = 4, col = "black")

# Show the map
print(map1)


# Create labels
Label <- FINAL %>%
  group_by(borough) %>%
  summarise(label_long = mean(range(long)), label_lat = mean(range(lat)), record = mean(record))

# Customize your map
map <- ggplot(FINAL, aes(long, lat, group = group))+
        geom_polygon(aes(fill = record), color = "white")+
        scale_fill_gradient(low = "#ffd1d1", high = "#f22929") +
        coord_equal() +
        theme_void() + 
        labs(title = "New York City murders per borough (2018)",
        caption = "Source: SKEMA Quantum Studio") +
        geom_text(data = Label, 
            mapping = aes(x = label_long, y = label_lat, label = record, group = NA),
            cex = 4, col = "black")

# Show the map
print(map)


We hope this helped you create your own advanced static map !


Sources

Supplementary Homicide Report: 2018 - NYPD

NYC Borough Shapefile NYC Planning


Follow SKEMA Global Lab in Augmented Intelligence

Warin, Thierry. 2019. “SKEMA Quantum Studio: A Technological Framework for Data Science in Higher Education.” https://doi.org/10.6084/m9.figshare.8204195.v2.

Citation

For attribution, please cite this work as

Gill & Warin (2020, March 9). Blog: How to create advanced static maps. Retrieved from https://blog.skemagloballab.io/posts/2020-03-09-advancedstaticmap/

BibTeX citation

@misc{gill2020how,
  author = {Gill, Anne Sophie and Warin, Thierry},
  title = {Blog: How to create advanced static maps},
  url = {https://blog.skemagloballab.io/posts/2020-03-09-advancedstaticmap/},
  year = {2020}
}