简体   繁体   English

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

[英]How to separate edge label from edge in igraph?

I would like to move the position of the edge label so that it is not on top of it.我想移动边缘标签的位置,使其不在其顶部。 Here is a little example:这是一个小例子:

 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)

In my example, the labels are on the edges and I want them to move perpendicular to the edge a little bit.在我的示例中,标签位于边缘,我希望它们稍微垂直于边缘移动。

Sorry to be the guy that says "How about using library(x)?"很抱歉成为那个说“使用 library(x) 怎么样?”的人。

My code using ggraph?我的代码使用 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()

igraph plotting has parameters edge.label.x and edge.label.y for placing the edge labels, but these must be specified in the coordinates used for making the plot. igraph 绘图具有用于放置边缘标签的参数edge.label.xedge.label.y ,但必须在用于绘制绘图的坐标中指定这些参数。 To get the right coordinates, you need to take control of the layout yourself.要获得正确的坐标,您需要自己控制布局。 @GaborCsardi suggested something like this in his comment, but implementing this is complicated enough that I think it deserves a full answer. @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) 

Now, instead of just plotting, we capture the layout of the vertices so that we can use it.现在,我们不只是绘图,而是捕获顶点的布局,以便我们可以使用它。 I set the random seed for reproducibility.我设置了可重复性的随机种子。

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

The layout gives xy coordinates for the vertices that we can use for plotting.布局给出了我们可以用于绘图的顶点的 xy 坐标。 We want to use those positions to compute where we will write the edge labels.我们想使用这些位置来计算我们将在哪里写边缘标签。 We will start by just computing the centers of the edges and then adjusting the positions perpendicular to the edges.我们将首先计算边缘的中心,然后调整垂直于边缘的位置。 One fine point: if an edge is nearly horizontal, the slope of the perpendicular is nearly infinite, so the calculation of the perpendicular displacement may cause problems.一个很好的点:如果一条边几乎是水平的,那么垂线的斜率几乎是无限的,因此垂直位移的计算可能会出现问题。 We will test for this and sidestep that problem.我们将对此进行测试并回避该问题。

## 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
    }
}

Now we can plot and specify a better position for the edge labels.现在我们可以为边缘标签绘制并指定一个更好的位置。 By default, plotting of igraph objects rescales the layout to the range [-1,1] for both the x and y axes.默认情况下,绘制 igraph 对象会将布局重新缩放到 x 轴和 y 轴的范围 [-1,1]。 If that happens, the values in the layout no longer correspond to positions on the graph.如果发生这种情况,布局中的值不再对应于图形上的位置。 So we will use rescale=FALSE .所以我们将使用rescale=FALSE But igraph still wants to plot in the range [-1,1], so we also have to set xlim and ylim.但是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)

带有移动边缘标签的图形

The adjustment distance d = 0.03 is somewhat arbitrary.调整距离d = 0.03有点随意。 I picked it to make this graph look nice.我选择它是为了让这个图表看起来不错。 If you have a more complicated graph, you might want to adjust that distance.如果您有更复杂的图形,您可能需要调整该距离。

You can move the edge labels vertically by adding return characters.您可以通过添加返回字符来垂直移动边缘标签。 You can move them horizontally by adding spaces.您可以通过添加空格来水平移动它们。 For example,例如,

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM