一个让R igraph箭头大小与边缘宽度匹配的技巧

18
尽管手册说明这将是一个未来的功能:
箭头大小。目前这是一个常数,因此对于每个边缘都是相同的。如果提交了一个向量,则仅使用第一个元素,即如果这是从边缘属性中获取的,则仅使用第一个边缘的属性用于所有箭头。这在将来可能会改变。
默认值为1。
我想知道是否有一种方法可以绕过,使箭头大小与边缘宽度匹配(每个边缘都有自己的宽度)。
d <- data.frame(start=c("a","a","b","c"),end=c("b","b","c","b"), size=rnorm(4))


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

plot(graph,
     vertex.color="white",
     edge.width=E(graph)$size*20,
     edge.arrow.size=E(graph)$size)

enter image description here

1个回答

13

嗯,有一个技巧,您需要将图绘制多次,每次仅绘制给定子集的边,使用“正确”的箭头大小,并绘制与不同边宽度数量相同的次数。使用add=TRUE参数在彼此之上绘制它们。也许您还想只绘制一次顶点。

顺便说一句,您可以在https://github.com/igraph/igraph/issues上提交此功能请求。

编辑:以下是一个示例:

library(igraph)

## (almost) your example data
d <- data.frame(start=c("a","a","b","c"),
                end=c("b","b","c","b"),
                size=1:4)
graph <- graph.data.frame(d, directed=TRUE)

## The plotting function
eqarrowPlot <- function(graph, layout, edge.lty=rep(1, ecount(graph)),
                        edge.arrow.size=rep(1, ecount(graph)),
                        vertex.shape="circle",
                        edge.curved=autocurve.edges(graph), ...) {
  plot(graph, edge.lty=0, edge.arrow.size=0, layout=layout,
       vertex.shape="none")
  for (e in seq_len(ecount(graph))) {
    graph2 <- delete.edges(graph, E(graph)[(1:ecount(graph))[-e]])
    plot(graph2, edge.lty=edge.lty[e], edge.arrow.size=edge.arrow.size[e],
         edge.curved=edge.curved[e], layout=layout, vertex.shape="none",
         vertex.label=NA, add=TRUE, ...)
  }
  plot(graph, edge.lty=0, edge.arrow.size=0, layout=layout,
       vertex.shape=vertex.shape, add=TRUE, ...)
  invisible(NULL)
}

## Test
eqarrowPlot(graph, layout.auto(graph), edge.arrow.size=E(graph)$size/3,
            edge.width=E(graph)$size)

图表

非常宽的边缘看起来相当不好。


我刚试了一下,有几个问题。当我用我给出的例子尝试时,它会抛出一个错误。示例代码:`d <- data.frame(start=c("a","a","b","c"),end=c("b","b","c","b"), size=rnorm(4))for(i in 1:nrow(d)){ graph <- graph.data.frame(d[1,], directed=T) plot.new() plot(graph, vertex.color="white", edge.width=E(graph)$size*20, edge.arrow.size=E(graph)$size, add=T) }`如果我使用自己的数据(其中还包含顶点的坐标,在每个循环中绘制一个顶点),是否有一种方法可以绘制所有顶点,然后逐个选择每个边缘? - Etienne Low-Décarie
1
@EtienneLow-Décarie:添加了一个示例。 - Gabor Csardi
@GaborCsardi 很好。我认为iGraph在这方面并不特别灵活。 - victor_v

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