igraph 绘图有参数edge.label.x
and edge.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
。但igraphstill想要在[-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
有点随意。我选择它是为了让这个图表看起来更漂亮。如果您有更复杂的图表,您可能需要调整该距离。