如何在igraph中将边缘标签与边缘分离?

14

我想移动边缘标签的位置,使其不在顶部。

这里有一个小例子:

 g <- graph.empty(n=3) 
 g <- graph(c(1,2,3,2,1,3), directed=T)
 E(g)$weight <- c(3,2,5) 
 plot(g, edge.label = E(g)$weight)

在我的例子中,标签位于边缘上,我希望它们沿着边缘垂直移动一小段距离。

3
据我所知,你只能通过根据顶点的坐标自己绘制边缘标签来完成这个操作。 - Gabor Csardi
3个回答

3
您可以通过添加回车符垂直移动边缘标签。您可以通过添加空格来水平移动它们。例如,
plot(g, edge.label = c(" 3","2\n","5\n"))

3

igraph绘图有参数edge.label.xedge.label.y,用于放置边缘标签,但这些必须在制作图表时使用的坐标中指定。为了获得正确的坐标,您需要自己控制布局。 @GaborCsardi 在他的评论中建议了类似于这样的内容,但实现起来足够复杂,我认为它值得一篇完整的回答。

## Setup - your example graph
library(igraph)
g <- graph.empty(n=3) 
g <- graph(c(1,2,3,2,1,3), directed=T)
E(g)$weight <- c(3,2,5) 

现在,我们不仅仅是绘制图形,还要捕获顶点的布局以便我们可以使用它。我设置了随机种子以保证可重复性。

set.seed(1234)
LO = layout_nicely(g)

该布局给出了用于绘图的顶点的x-y坐标。我们希望使用这些位置计算我们将写入边缘标签的位置。我们将首先只计算边缘的中心,然后根据边缘垂直调整位置。一个细节是:如果一条边几乎水平,则垂直线的斜率几乎为无限大,因此垂直位移的计算可能会导致问题。我们将测试此问题并规避该问题。
## Start with the centers of the edges (on line)
ELx = rep(0, ecount(g))
ELy = rep(0, ecount(g))
for(i in 1:ecount(g)) {
    ELx[i] = (LO[ends(g,i)[1],1] + LO[ends(g,i)[2],1])/2
    ELy[i] = (LO[ends(g,i)[1],2] + LO[ends(g,i)[2],2])/2 }

## Adjust perpendicular to line
d = 0.03
for(i in 1:ecount(g)) {
    if(abs(LO[ends(g,i)[1],2] - LO[ends(g,i)[2],2]) < 0.1) {
        ## This avoids problems with horizontal edges
        ELy[i] = ELy[i] + shift 
    } else {
        S = (LO[ends(g,i)[2],1] - LO[ends(g,i)[1],1]) / 
            (LO[ends(g,i)[1],2] - LO[ends(g,i)[2],2])
        shift = d / sqrt(1 + S^2)
        ELx[i] = ELx[i] + shift
        ELy[i] = ELy[i] + S*shift
    }
}

现在我们可以绘制和指定边缘标签的更好位置。默认情况下,绘制igraph对象会将布局重新调整为x和y轴的范围[-1,1]。如果这样做,布局中的值不再对应于图上的位置。因此,我们将使用rescale=FALSE。但是igraph仍然希望在范围[-1,1]内绘制,因此我们还必须设置xlim和ylim。
plot(g, layout=LO, edge.label = E(g)$weight,
    rescale=FALSE, xlim=range(LO[,1]), ylim=range(LO[,2]), 
    edge.label.x=ELx, edge.label.y=ELy)

带有偏移边标签的图形

调整距离d = 0.03有些随意。我选择它是为了使这个图看起来好看。如果你有一个更复杂的图,你可能需要调整那个距离。


这个问题一直在抛出错误:LO [ends (g,i) [1],2]中没有数组的'dimnames'属性 - DrBwts
@DrBwts 我刚刚开始了一个新的R会话,并按照上面的代码精确地运行了它。我没有收到任何错误提示。 - G5W
它适用于您答案中的示例图,但当我读入一个有向加权图时,它会抛出上述错误。 - DrBwts
我最好的建议是:1. 尝试创建一个包含问题的小例子。2. 以这个问题为参考,发表一个新的问题。在你的“小型”网络上使用 dput 命令,这样我就能看到出了什么问题。 - G5W

2
抱歉我要说“使用库(x)怎么样?”。我的代码用ggraph?翻译后:抱歉我要提出“是否考虑使用库(x)呢?”我的代码是用ggraph实现的?
library(igraph)
library(ggraph)

g <- graph.empty(n=3) 
g <- graph(c(1,2,3,2,1,3), directed=T)
E(g)$weight <- c(3,2,5) 

#your plot
plot(g, edge.label = E(g)$weight)


#using ggraph
ggraph(graph = g) +
  geom_node_circle(size = 1, mapping = aes(r =0.03), fill="goldenrod") +
  geom_edge_link(mapping = aes (label = weight),
                 arrow = arrow(type = "closed", angle = 15), 
                 end_cap = circle(8, 'mm'), , 
                 start_cap = circle(8, 'mm'), 
                 colour="grey",
                 label_dodge  = unit(5, "mm"),
                 angle_calc = "along") +
  geom_node_text(mapping = aes(label = "2")) +
  theme_graph()

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