NuBu
NuBu

Reputation: 11

Plot result of all_simple_paths (igraph, R)

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

Answers (2)

nJGL
nJGL

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

NuBu
NuBu

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

Related Questions