Reputation: 11
I have a large spatially explicit igraph object (2746 nodes/ 3205 edges) showing sediment transport pathways in a catchment. With the command all_simple_paths I extracted all paths that start at defined source nodes and end up at the outlet of the catchment (using lapply). The result of all_simple_paths is a list of 1841 elements, with each element showing the vertex ids of the respective path. Now I am struggling to plot these paths. I would like to plot all the paths in a spatially explicit way in one image. Like a subset of the graph built up by all the paths that reach the outlet.
"plot" gives the error :
Error in xy.coords(x, y, xlabel, ylabel, log) :
'x' is a list, but does not have components 'x' and 'y'
The complete graph I plot with "ggraph", but for the "outlet graph" also this command gives an error:
Error in create_layout.default(graph, layout, ...) :
No layout function defined for objects of class list
Probably it is very easy to solve, but I tried already various possibilities and didn't manage to get the plot.
Here a little (hopefully not too simplified) example:
`library(igraph)
a <- c(1,2,2,3,4,4,7,7,7)
b <- c(2,3,10,4,5,6,8,9,3)
c <- c("rf","se","se","ft","fd","ft","st", "st","st")
edges <- cbind(a,b,c)
id <- c(1,2,3,4,5,6,7,8,9,10)
x <- c(623096,622839,622475,622581,622480,622376,620313,621551,621142,622927)
y <- c(5149975,5150159,5150591,5151056,5151367,5151399,5150039,5150077,5150649,5150274)
nodes <- cbind(id,x,y)
my_graph <- graph_from_data_frame(edges, directed = TRUE,vertices = nodes)
plot(my_graph)
graph_outlet <- all_simple_paths(my_graph,from=1,to= 6,mode = "out")
plot (graph_outlet)`
Thanks a lot already in advance!
Upvotes: 1
Views: 698
Reputation: 864
You can plot the respective paths by making sub-graphs of each path in graph_outlet
like:
sub_graphs <- lapply(graph_outlet, function(vs) induced_subgraph(my_graph, vs))
plot(sub_graphs[[1]])
Be mindful of what kind of objects the various igraph-functions return. Look at these lines in your example code:
graph_outlet <- all_simple_paths(my_graph,from=1,to= 6,mode = "out")
class(graph_outlet[[1]])
class(my_graph)
Edit:
I realised that you seek to visualise all paths in the same graph. I make a small manipulation to your example data to create multiple paths between vertices 1 and 6, and then color vertices and edges in the entire graph to highlight the paths:
# Your example data with path between 4-->10
a <- c(1,2,2,3,4,4,7,7,7,10)
b <- c(2,3,10,4,5,6,8,9,3,4)
c <- c("rf","se","se","ft","fd","ft","st", "st","st","st")
edges <- cbind(a,b,c)
id <- c(1,2,3,4,5,6,7,8,9,10)
x <- c(623096,622839,622475,622581,622480,622376,620313,621551,621142,622927)
y <- c(5149975,5150159,5150591,5151056,5151367,5151399,5150039,5150077,5150649,5150274)
nodes <- cbind(id,x,y)
my_graph <- graph_from_data_frame(edges, directed = TRUE,vertices = nodes)
# Preferences
FROM_V <- 1
TO_V <- 6
# Calculate all simple paths from FROM_V to TO_V as list of vertecy sequences
graph_outlet <- all_simple_paths(my_graph,from=FROM_V,to=TO_V, mode = "out")
# Build sub-graphs to test
sub_graphs <- lapply(graph_outlet, function(vs) induced_subgraph(my_graph, vs))
plot(sub_graphs[[1]])
plot(my_graph)
# Colour and style vertecies
V(my_graph)$color <- "white"
V(my_graph)$color[unique(unlist(graph_outlet))] <- "gray"
V(my_graph)$color[c(FROM_V,TO_V)] <- "yellow"
# Colour each of the paths
E(my_graph)$color <- "gray"
lapply(graph_outlet, function(x) E(my_graph, path=x)$color <<- "black")
# Plot all paths and mark the group of vertecies through which paths flow
plot(my_graph)
plot(my_graph, mark.groups=unique(unlist(graph_outlet)))
Upvotes: 2
Reputation: 11
I managed to find an answer myself ;) Posting it just in case someone might have the same question one day.
Here the code I applied now on my full data set. The result "subbi" is an igraph object and thus it is possible to plot it with ggraph. (V_source are the predefined source nodes, outlet_node the node where the paths shall end):
paths2 <- lapply(V_source[1:length(V_source)] , function(x) all_simple_paths(my_graph, x , to=outlet_node, mode = "out") )
A1 <- unlist(paths2, recursive = FALSE)
C <- list()
for (i in 1:length(A1)) {
C[[i]] = E(graph=my_graph, path=A1[[i]])$ EdgeID
}
seledges <- lapply(C, function(x) E(my_graph)[EdgeID %in% x])
subbi <- subgraph.edges(my_graph,unlist(seledges))
Upvotes: 0