Search code examples
rplotgraphigraph

How to plot an igraph object on a vector map in R


I use the igraph and sf packages.

I have an igraph object whose vertices have spatial coordinates geo_dist_graph. The vertices names and coordinates look like this:

grid_grid <- 
structure(list(coords.x1 = c(15.504078, 15.704078, 15.904078, 
15.104078, 15.304078, 15.504078, 15.704078, 15.104078, 15.304078, 
15.704078, 14.904078, 14.304078, 13.904078, 14.704078, 13.704078, 
14.104078, 14.704078, 14.904078, 13.704078, 13.904078, 14.704078, 
13.704078, 13.904078, 14.304078), 
coords.x2 = c(43.835623, 43.835623, 
43.835623, 44.035623, 44.035623, 44.035623, 44.035623, 44.235623, 
44.235623, 44.235623, 44.435623, 44.635623, 44.835623, 44.835623, 
45.035623, 45.035623, 45.035623, 45.035623, 45.235623, 45.235623, 
45.235623, 45.435623, 45.435623, 45.435623), 
g9.nodes = c(27, 
28, 29, 40, 41, 42, 43, 55, 56, 58, 69, 81, 94, 98, 108, 110, 
113, 114, 123, 124, 128, 138, 139, 141)), 
class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
"14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"
))

The graph is from a simple squared adjacency matrix:

geo_dist_graph <- 
  structure(c(NA, 1, 1, NA, NA, 1, 1, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, NA, 1, NA, NA, NA, 
1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, 1, 1, NA, NA, NA, NA, 1, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, NA, 
NA, 1, 1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, 1, NA, 1, NA, NA, 1, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, NA, NA, NA, 1, NA, 
1, NA, 1, 1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, 1, 1, 1, NA, NA, 1, NA, NA, NA, 1, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, NA, NA, NA, 
NA, 1, NA, 1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, 1, 1, 1, NA, 1, NA, 1, 1, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, 1, NA, 
1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, 1, 1, NA, NA, NA, NA, 1, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, 1, 1, NA, 1, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, NA, NA, 1, 1, 
NA, NA, NA, 1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, 1, 1, NA, NA, NA, NA, 1, 1, NA, NA, 1, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, NA, NA, 1, NA, 
NA, 1, 1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, 1, 1, NA, 1, NA, NA, NA, NA, 1, NA, NA, NA, 1, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, NA, NA, NA, 1, 
NA, NA, 1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, 1, NA, NA, 1, NA, NA, NA, 1, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, NA, NA, NA, 
NA, 1, NA, 1, 1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, 1, NA, 1, 1, NA, NA, 1, NA, NA, 1, 1, 1, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, NA, NA, 1, 1, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, 1, 1, NA, NA, 1, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, 
1, NA, 1, NA, 1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, 1, NA, NA, NA, 1, NA, NA, 1, NA), 
.Dim = c(24L, 
24L))

colnames(geo_dist_graph) <- grid_grid$g9.nodes
row.names(geo_dist_graph) <- grid_grid$g9.nodes

geo_dist_graph <- graph_from_adjacency_matrix(geo_dist_graph, mode = "upper", diag = F)

The spatial coordinates where attched this way:

V(geo_dist_graph)$x <- 
  grid_grid$coords.x1[match(V(geo_dist_graph)$name, grid_grid$g9.nodes)]

V(geo_dist_graph)$y <- 
  grid_grid$coords.x2[match(V(geo_dist_graph)$name, grid_grid$g9.nodes)]

The graph is correclty plotted in space when using the plot function. But when I try to add a basemap like this plot(map_crop_sp, add = T), the map doesn't show behind the graph, but there is no error message.

The map is vector map, don't know if it's important. Here is the code used to create it.

map <- st_read("ne_10m_coastline/ne_10m_coastline.shp")
map_crop <- st_crop(map, xmin = 13.304078, ymin = 43.635623, xmax = 16.503846, ymax = 45.60185)
map_crop_sp <- as(map_crop, Class = "Spatial")

Solution

  • Answer

    Since the igraph should be on top of the map, I plot it second. I also added rescale = F:

    plot(map_crop_sp)
    plot(geo_dist_graph, add = T, rescale = F)
    

    enter image description here

    Rationale

    I typed ?plot.igraph. From there, I found ?igraph.plotting. It seems that plotting an igraph object rescales it (plot(..., rescale = TRUE):

    Logical constant, whether to rescale the coordinates to the [-1,1]x-1,1 interval. This parameter is not implemented for tkplot.

    Defaults to TRUE, the layout will be rescaled.