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

5

我正在尝试在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)]

但是这给我带来了一个“无效的索引”错误。您有什么其他建议吗?
4个回答

3

您可以使用"dplyr"和"tidyr"包,结合"as_data_frame"和"graph_from_data_frame"函数,轻松地重新排列边缘并重构图形:

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

3
igraph按照图的边缘列表中出现的顺序绘制边缘,所以您是正确的,具有更高ID的边缘将绘制在具有较低ID的边缘之上。不幸的是,igraph没有提供一种简单的方法来重新排序图的边缘(虽然它有一个名为permute.vertices的函数,可以让您对顶点进行置换),所以我现在唯一能想到的方法是:您需要构建另一个图,其中边缘按照“正确的顺序”排列。make_graph确保按您指定的顺序存储边缘,并且我认为graph_from_data_frame也是如此。

另一个选项(如果您不想重建整个图)是将图绘制两次:首先,您绘制“不太重要”的边缘并将重要边缘的宽度设置为零,然后在其上面绘制重要的边缘。

如果您希望在igraph的即将推出的版本中支持边缘置换,请在Github上提交特性请求


谢谢,Tamás!对我来说,绘制两次的解决方案效果最好。我使用 set.seed() 确保我的布局是可重现的,并在第一次绘图后使用 E(test)[E(test)$color=="gray"]$color <- NA 确保灰色边缘被隐藏,并在第二次调用 plot() 时使用 add=TRUE - cjolley
你也可以显式地调用一个布局函数并将其结果存储在变量中 - 然后您可以将此变量稍后传递给 plot() 函数中的 layout=... 参数。 - Tamás
您还可以生成一次布局,然后将其存储到图形中。如果设置g$layout属性,则绘图将自动使用存储在其中的布局。在这种情况下,您将布局存储到图形中,然后将新图形布局设置为旧图形布局。 - wmsmith
嗨@wmsmith,我已经尝试了您的建议,使用plot.igraph和add=TRUE以及旧图形的布局。但是与旧图相比,新绘图给出了错误的位置。我还没有检查原因。 - pengchy

1
< p > 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) 

随着情节的展开,红边缘变成了最上面的一条: 新图表的情节:test2

0

或者你可以根据你想要排序的变量简单地重新排列你的数据,然后将其提供给igraph。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接