【问题标题】:How to separate edge label from edge in igraph?如何在igraph中将边缘标签与边缘分开?
【发布时间】:2014-05-27 20:20:19
【问题描述】:

我想移动边缘标签的位置,使其不在其顶部。 这是一个小例子:

 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)

在我的示例中,标签位于边缘,我希望它们稍微垂直于边缘移动。

【问题讨论】:

  • AFAIK,你只能通过自己绘制边缘标签来做到这一点,基于顶点的坐标。

标签: r label igraph graph-theory


【解决方案1】:

很抱歉成为那个说“使用 library(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()

【讨论】:

    【解决方案2】:

    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有些随意。我选择它是为了让这张图看起来不错。如果您有更复杂的图表,您可能需要调整该距离。

    【讨论】:

    • 这一直给我报错Error in LO[ends(g, i)[1], 2] : no 'dimnames' attribute for array
    • @DrBwts 我刚刚开始了一个新的 R 会话,并完全按照上面显示的方式运行了我的代码。我没有错误。
    • 它适用于您答案中的示例图,但是当我阅读有向加权图时,它会引发上述错误
    • 我最好的建议是1.尝试做一个有问题的小例子。 2. 发布一个新问题并引用此问题。在你的 SMALL 网络上使用dput,这样我就可以看到发生了什么,
    【解决方案3】:

    您可以通过添加返回字符来垂直移动边缘标签。您可以通过添加空格来水平移动它们。例如,

    plot(g, edge.label = c(" 3","2\n","5\n"))
    

    【讨论】:

      猜你喜欢
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-03
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      • 1970-01-01
      相关资源
      最近更新 更多