Petr
Petr

Reputation: 1817

Plotting neighborhoods network to a ggplot maps

How to insert spatial network plot to a ggplot

library(rgeos) 
library(rgdal)
library(dplyr)
require(maps)
require(viridis)
library(ggplot2)
library(spdep)


some.eu.countries <- c(
  "Portugal", "Spain", "France", "Switzerland", "Germany",
  "Austria", "Belgium", "UK", "Netherlands",
  "Denmark", "Poland", "Italy", 
  "Croatia", "Slovenia", "Hungary", "Slovakia",
  "Czech republic"
)
# Retrievethe map data

some.eu.maps <- map_data("world", region = some.eu.countries)

# Compute the centroid as the mean longitude and lattitude
region.lab.data <- some.eu.maps %>%
  group_by(region) %>%
  summarise(long = mean(long), lat = mean(lat))

cns <- knearneigh(cbind(region.lab.data$long, region.lab.data$lat), k=3, longlat=T) 
scnsn <- knn2nb(cns, row.names = NULL, sym = T) 
cns
scnsn
cS <- nb2listw(scnsn) 
cS
summary(cS)

# Plotting neighbours network
plot(cS, cbind(region.lab.data$long, region.lab.data$lat))


# Now plotting countries
ggplot(some.eu.maps, aes(x = long, y = lat)) +
  geom_polygon(aes( group = group, fill = region), colour = "black")+
  geom_point(aes(region.lab.data$long, region.lab.data$lat), data = region.lab.data, size = 6)

I would like to insert #Plotting neighbours network to a # Now plotting countries in another words I would like to have a ggplot of countries and also see network of neighbours in it.

Upvotes: 2

Views: 690

Answers (2)

Ian Buller
Ian Buller

Reputation: 27

Here is an example using the sf and sfdep packages for counties in a U.S. state. We can display the "weights" feature of the neighborhoods network as the size of the line segments by scaling the size aesthetic with + scale_size_identity().

library(ggplot2)
library(sf)
library(sfdep)
library(tigris)

# County geometries of Georgia, U.S.A.
shp_ga <- counties(state = "Georgia", cb = TRUE)

# NAD83/UTM zone 17N geospatial projection
proj_ga <- st_transform(shp_ga, crs = 26917)

# First order contiguity (Queen's case by default)
nb <- st_contiguity(st_geometry(proj_ga)) 

# Contiguity-based spatial weights matrix
nbw <- st_weights(nb)

# County centroids
centroids <- st_centroid(proj_ga)

# Assign lat and long for centroid connections in a dataframe
## Modifying code from @StupidWolf's answer
## https://stackoverflow.com/a/58540394/6784787
da <- data.frame(from = rep(1:length(nbw), attributes(nbw)$comp$d),
                 to = unlist(nb),
                 weight = unlist(nbw))
da <- cbind(da, 
            st_coordinates(centroids)[da$from, 1:2], 
            st_coordinates(centroids)[da$to, 1:2])
colnames(da)[4:7] <- c("longitude", "latitude", "long_to", "lat_to")

# Plot counties and line segments with size scaled by "weights" feature
g <- ggplot() +
     geom_sf(data = proj_ga, fill = "white", color = "black") + 
     geom_sf(data = centroids, color = "blue", size = 1) + 
     geom_segment(data = da,
                  aes(x = longitude, y = latitude,
                      xend = long_to, yend = lat_to,
                      size = weight),
                  color = "red", alpha = 0.5) +
     scale_size_identity() +
     theme_minimal()

Queen's case continuity neighborhood of Georgia, U.S.A. counties

Upvotes: 1

StupidWolf
StupidWolf

Reputation: 46908

I looked under plot.nb, which is the plot method of your nb2listw output, and i think it basically makes a segment for all connections between your input.

# Now plotting countries
g = ggplot(some.eu.maps, aes(x = long, y = lat)) +
  geom_polygon(aes( group = group, fill = region), colour = "black")+
  geom_point(aes(region.lab.data$long, region.lab.data$lat), data = region.lab.data, size = 6)

# take out the connections from your nb object
# and assign them the lat and long in a dataframe
n = length(attributes(cS$neighbours)$region.id)
DA = data.frame(
from = rep(1:n,sapply(cS$neighbours,length)),
to = unlist(cS$neighbours),
weight = unlist(cS$weights)
)
DA = cbind(DA,region.lab.data[DA$from,2:3],region.lab.data[DA$to,2:3])
colnames(DA)[4:7] = c("long","lat","long_to","lat_to")
#plot it using geom_segment
g + geom_segment(data=DA,aes(xend=long_to,yend=lat_to),size=0.3,alpha=0.5)

This is what I got (caveat, I don't know what to do with the weights):

enter image description here

Upvotes: 2

Related Questions