A while back on StackOverflow, I answered a question on how to produce a map which showed how many polygons away a location was from another. This blog provides an update on how this can be used, with some slight tweaks to the answer to expand on the original. A lot of this content is based around the original from Roger Bivand here.
In order to calculate neighbouring polygons, we need to form a network of nodes for the data. This is done using the igraph (file. 2020) spdep (Bivand 2020) and spatialreg (Bivand and Piras 2019) packages. We also use the raster (Hijmans 2020) package to download some example data, and ggplot2 (Wickham et al. 2020) for the final visualisation.
# Loading example data library(raster) # loads shapefile # Data Analysis library(igraph) # build network library(spdep) # builds network library(spatialreg) # Visualisation library(RColorBrewer) # for plot colour palette library(ggplot2) # plots results library(tmap)
First downloading the data as follows. The input data is shown in Figure 1. You could easily provide your own shapefile here instead or run the code for a different country by changing the three-digit code. For my example, I have selected Hungary:
# Load Data boundaries <- raster::getData(name = "GADM", country = "HUN", level = 2) # Show data tm_shape(boundaries) + tm_polygons()
poly2nb function is used to calculate neighbouring regions, based on contiguous boundaries, that is sharing one or more boundary point. The resulting mesh and coordinates is shown in Figure 2
# Find neighbouring areas nb_q <- poly2nb(boundaries) # Plot original results coords <- coordinates(boundaries) # Show the results plot(boundaries) plot(nb_q, coords, col="grey", add = TRUE)
With this mesh, we can then calculate the shortest path between two locations. The follow function returns a list for each and every pair of polygons.
# Sparse matrix nb_B <- nb2listw(nb_q, style="B", zero.policy=TRUE) B <- as(nb_B, "symmetricMatrix") # Calculate shortest distance g1 <- graph.adjacency(B, mode="undirected") sp_mat <- shortest.paths(g1)
Having made the calculations, the data can now be formatted to get into plotting format, so the shortest path matrix is merged with the spatial dataframe.
# Name used to identify data referenceCol <- boundaries$GID_2 # Rename spatial matrix sp_mat2 <- as.data.frame(sp_mat) sp_mat2$id <- rownames(boundaries@data) names(sp_mat2) <- paste0(referenceCol) # Add distance to shapefile data boundaries@data <- cbind(boundaries@data, sp_mat2) boundaries@data$id <- rownames(boundaries@data)
The data is now in a suitable format to display. Using the basic function
spplot we can get a graph quite quickly:
tm_shape(boundaries) + tm_polygons("HUN.15.5_1", n = 15)
Plotting in ggplot2
I prefer ggplot for plotting more complex graphs as you can control the styling easier. Fortunately, ggplot2 now directly supports spatial data through
geom_sf format. I have customised it a bit by removing elements which aren’t required and added a background. The final map is shown below in Figure 3.
# Convert data to sf format boundaries_sf <- sf::st_as_sf(boundaries) ggplot(boundaries_sf) + geom_sf(aes(fill = HUN.15.5_1)) + geom_sf(fill = "grey", alpha = ifelse(boundaries_sf$GID_2 == "HUN.15.5_1", 1, 0)) + scale_fill_gradient2(low = "#d73027", mid = "#fee08b", high = "#1a9850", midpoint = 10) + labs(fill = "Distance from \nselected zone") + theme( axis.line = element_blank(), axis.text.x = element_blank(), axis.text.y = element_blank(), axis.ticks = element_blank(), axis.title.x = element_blank(), axis.title.y = element_blank(), panel.grid.minor = element_blank(), panel.grid.major = element_blank(), plot.background = element_rect(fill = "#f5f5f2", color = NA), panel.background = element_rect(fill = "#f5f5f2", color = NA), legend.background = element_rect(fill = "#f5f5f2", color = NA), panel.border = element_blank())
Bivand, Roger. 2020. Spdep: Spatial Dependence: Weighting Schemes, Statistics. https://CRAN.R-project.org/package=spdep.
Bivand, Roger, and Gianfranco Piras. 2019. Spatialreg: Spatial Regression Analysis. https://CRAN.R-project.org/package=spatialreg.
file., See AUTHORS. 2020. Igraph: Network Analysis and Visualization. https://CRAN.R-project.org/package=igraph.
Hijmans, Robert J. 2020. Raster: Geographic Data Analysis and Modeling. https://CRAN.R-project.org/package=raster.
Wickham, Hadley, Winston Chang, Lionel Henry, Thomas Lin Pedersen, Kohske Takahashi, Claus Wilke, Kara Woo, Hiroaki Yutani, and Dewey Dunnington. 2020. Ggplot2: Create Elegant Data Visualisations Using the Grammar of Graphics. https://CRAN.R-project.org/package=ggplot2.