【问题标题】:Using igraph, how to force curvature when arrows point in opposite directions使用 igraph,当箭头指向相反方向时如何强制曲率
【发布时间】:2023-11-03 13:44:01
【问题描述】:

autocurve.edges 在 igraph 图中弯曲边缘的工作非常出色,因此当它们指向同一方向时它们不会重叠。但是,当它们指向相反的方向时,不会应用曲率。

d <- data.frame(start=c("a","a","b","c"),end=c("b","b","c","b"))


graph <- graph.data.frame(d, directed=T)

plot(graph,
     vertex.color="white")

问题在于 b 和 c(或 c 和 b)之间的箭头。

除了手动指定曲率,还有什么建议吗?

【问题讨论】:

    标签: r plot igraph


    【解决方案1】:

    我会使用 edge.curved 选项和 autocurve.edges 使用的相同 seq 调用。

    plot(graph,
         vertex.color="white", edge.curved=seq(-0.5, 0.5, length = ecount(graph)))
    

    编辑:

    正如 Étienne 指出的那样,该解决方案还可以弯曲边缘以进行独特的观察。解决方案是修改autocurve.edges 函数。这是我修改后的函数autocurve.edges2。基本上,它会生成一个向量,该向量仅弯曲非唯一边缘。

    autocurve.edges2 <-function (graph, start = 0.5)
    {
        cm <- count.multiple(graph)
        mut <-is.mutual(graph)  #are connections mutual?
        el <- apply(get.edgelist(graph, names = FALSE), 1, paste,
            collapse = ":")
        ord <- order(el)
        res <- numeric(length(ord))
        p <- 1
        while (p <= length(res)) {
            m <- cm[ord[p]]
            mut.obs <-mut[ord[p]] #are the connections mutual for this point?
            idx <- p:(p + m - 1)
            if (m == 1 & mut.obs==FALSE) { #no mutual conn = no curve
                r <- 0
            }
            else {
                r <- seq(-start, start, length = m)
            }
            res[ord[idx]] <- r
            p <- p + m
        }
        res
    }
    

    这是添加单个非相互边 (C->D) 时的结果:

    library(igraph)
    d <- data.frame(start=c("a","a","b","c","c"),end=c("b","b","c","b","d"))
    graph <- graph.data.frame(d, directed=T)
    curves <-autocurve.edges2(graph)
    plot(graph, vertex.color="white", edge.curved=curves)
    

    【讨论】:

    • 这是朝着正确方向迈出的一大步!谢谢。但是,这会导致所有边缘弯曲,甚至是独特的边缘。
    • 我刚刚发现了这个功能。非常好。谢谢。
    • 非常好的功能。我也谢谢你!