如何重新排列 igraph 图中边的顺序?

How can I rearrange the order of edges in an igraph plot?

我正在尝试在 igraph 中制作一个网络图,通过与其他边缘不同的颜色来突出显示某些重要的边缘。对于大图,它们经常被掩埋在其他图之下。例如:

library(igraph)
test <- barabasi.game(200,m=2)
E(test)$color <- "gray"
E(test)[1]$color <- "red"
sort(order(E(test)$color)[E(test)],decreasing=TRUE)
plot(test,
     vertex.label=NA,
     vertex.shape="none",
     vertex.size=0,
     edge.arrow.mode=0,
     edge.width=2) 

给我一个图,其中单个红色边缘位于底部。 如果我选择给编号更高的边(而不是#1)上色,它就更有可能不被掩埋。

所以在我看来,一种选择是以某种方式重新排列边缘。我试过了

E(test) <- E(test)[order(E(test)$color)]

但这让我得到一个 "invalid indexing" 错误。关于我还应该尝试什么的任何想法?

igraph 按照它们在图的边列表中出现的顺序绘制边,所以你是对的,具有较高 ID 的边将绘制在具有较低 ID 的边之上。不幸的是,igraph 没有提供一种简单的方法来重新排序图形的边缘(尽管它有一个名为 permute.vertices 的函数,它允许您排列顶点),所以我现在能想到的唯一方法是您需要构建另一个图,其中边在 "right order" 中。 make_graph 确保边完全按照您指定的顺序存储在图中,我认为 graph_from_data_frame.

也是如此

另一种选择(如果您不想重建整个图形)是绘制图形两次:首先绘制 "not-so-important" 边并将重要边的宽度设置为零,然后您在顶部绘制重要边缘。

如果您希望即将推出的 igraph 版本支持边排列,请在 Github 上 file a feature request

或者您可以简单地根据您希望订购的变量重新排列数据,然后将其提供给 igraph

您可以使用 "as_data_frame" 和 "graph_from_data_frame" 与 dplyr 和 tidyr 包结合使用重新排序的边来重建图形:

new_graph=graph_from_data_frame(d=as_data_frame(old_graph,what="edges") %>%
    arrange(desc(ordering_attribute)),
    vertices=as_data_frame(old_graph,what="vertices"))

如果您在旧图形上存储了布局,则需要手动传输它...

new_graph$layout = old_graph$layout

之所以E(test) <- E(test)[order(E(test)$color)]不能计算出来,是因为我们不允许将一个'igraph.es'变量赋值给另一个已经存在的变量或其自身;但是,我们可以使用 a <- E(test)[order(E(test)$color)] 创建一个新的 'igraph.es' 变量。因此,我们需要创建一个新图来从原始图中继承新的边顺序:

library(igraph)
test <- barabasi.game(200,m=2)
E(test)$color <- "gray"
E(test)[1]$color <- "red"

# to make a new graph:test2 whose edges are descended from the ordering edges of the orginal graph:test
test2 <- make_graph(as.vector(t(get.edgelist(test)[order(E(test)$color),])))
# to assign the attribute value to the edges of the new graph
E(test2)$color <- E(test)$color[order(E(test)$color)]

plot(test2,
 vertex.label=NA,
 vertex.shape="none",
 vertex.size=0,
 edge.arrow.mode=0,
 edge.width=2) 

如图所示,红色边缘成为最上面的边缘: