1
votes

ggnetwork: how to put geographic information on the vertex ?

ggnetwork(n, layout = "fruchtermanreingold", cell.jitter = 0.75)

The default node placement algorithm used by ggnetwork to produce these coordinates is the Fruchterman-Reingold force-directed layout algorithm. I would like to put geographical information (lat, long)

2
The answer below by @yosukesabai is correct (and should be marked as such), and I'll soon consider adding an option to remove the scaling if need be. You might want to check the dev version of the package: github.com/briatte/ggnetworkFr.

2 Answers

1
votes

The documentation says that

The layout argument will also accept user-submitted coordinates as a two-column matrix with as many rows as the number of nodes in the network.

So you can supply coordinates of nodes as matrix. But it uses scale function, and original values got lost, only relative positions kept. So need to undo the scaling, or modify source to bypass scaling. It's in somewhere near line 121 of R/fortify.network.R

0
votes

The option required to make ggnetwork work with geographic coordinates has just been added to the development version of the package.

Example below:

library(dplyr)
library(nycflights13)
library(network)
# IMPORTANT: install from `devtools` or `remotes`
# remotes::install_github("briatte/ggnetwork")
library(ggnetwork)
library(ggmap)
library(ggplot2)

# edges: flights
e <- select(flights, origin, dest) %>%
  group_by(origin, dest) %>%
  tally %>% 
  filter(origin != dest, n > 2500) %>%  # no self-loops + thinning
  filter(origin %in% airports$faa, dest %in% airports$faa) # lose SJU

# weighted directed network
n <- network::network(select(e, origin, dest), directed = TRUE)
set.edge.attribute(n, "weight", e$n) # weight = number of flights

# nodes: airports
y <- filter(airports, faa %in% e$origin | faa %in% e$dest) %>% 
  select(faa, lat, lon)

# sanity check (no missing airports)
stopifnot(nrow(y) == network.size(n))

# named geo coordinate vectors...
lat <- y$lat
names(lat) <- y$faa
lon <- y$lon
names(lon) <- y$faa
# ... as a (x, y) coordinate matrix
geo <- cbind(lon[ network.vertex.names(n) ], lat[ network.vertex.names(n) ])

# geographic network
g <- ggnetwork(n, layout = geo, scale = FALSE) %>% 
  rename(lon = x, lat = y)

# map background
map <- ggmap::get_map(c(left = min(geo[, 1]), bottom = min(geo[, 2]), right = max(geo[, 1]), top = max(geo[, 2])))
# map + network plot
ggmap::ggmap(map) +
  geom_point(data = g, aes(lon, lat)) +
  geom_edges(data = g, aes(lon, lat, xend = xend, yend = yend)) +
  geom_nodelabel(data = g, aes(label = vertex.names))

ggsave("map_example.png")

map example