如何用固定位置控制igraph图布局?

时间:2011-03-19 19:11:22

标签: r igraph

我正在尝试绘制网络可视化以类似于流程图。我对以下代码非常接近,但我有几个问题:

  1. 这是最佳布局()算法,还是我可以为每个节点手动分配位置>
  2. 如何确保这些节点在图中不重叠(就像在这里一样)?
  3. 我可以将一个节点指定为“锚点”或起点吗?即,我可以将“C”作为最顶层或最左侧的节点吗?
  4. 非常感谢!!

    library("igraph")
    L3 <- LETTERS[1:8]
    d <- data.frame(start = sample(L3, 16, replace = T), end = sample(L3, 16, replace = T),
                    weight = c(20,40,20,30,50,60,20,30,20,40,20,30,50,60,20,30))
    
    
    g <- graph.data.frame(d, directed = T)
    
    V(g)$name 
    E(g)$weight
    
    ideg <- degree(g, mode = "in", loops = F)
    
    col=rainbow(12) # For edge colors
    
    plot.igraph(g, 
      vertex.label = V(g)$name, vertex.label.color = "gray20",
      vertex.size = ideg*25 + 40, vertex.size2 = 30,
      vertex.color = "gray90", vertex.frame.color = "gray20",
      vertex.shape = "rectangle",
      edge.arrow.size=0.5, edge.color=col, edge.width = E(g)$weight / 10,
      edge.curved = T, 
      layout = layout.reingold.tilford)
    

2 个答案:

答案 0 :(得分:36)

igraph中的布局是在一个矩阵中定义的,每个节点有2列和一行。第一列表示其x位置,第二列表示其y位置,并且比例不相关(它总是重新调整以适合-1到1的绘图区域。您可以在绘图之前通过调用图形上的布局函数来获得此布局:

 l <-layout.reingold.tilford(g) 
 l
     [,1] [,2]
[1,]    0    0
[2,]   -1    3
[3,]    0    1
[4,]    0    3
[5,]    0    2
[6,]    0    4
[7,]    1    3

这样您可以手动以任何方式更改它,然后将其发送到绘图:

plot.igraph(g, 
  vertex.label = V(g)$name, vertex.label.color = "gray20",
  vertex.size = ideg*25 + 40, vertex.size2 = 30,
  vertex.color = "gray90", vertex.frame.color = "gray20",
  vertex.shape = "rectangle",
  edge.arrow.size=0.5, edge.color=col, edge.width = E(g)$weight / 10,
  edge.curved = T, 
  layout = l)

似乎您可以设置参数params来控制布局升技。这是一个包含参数root的列表,显然可以用来设置图的根。为此节点分配一些节点(重新记录,igraph使用C类似于节点的索引,第一个节点为0)。因此将根设置为“C”:

l <- layout.reingold.tilford(g,params=list(root=2))

编辑:RGraphViz还有一些很好的树形布局,可能值得一试。


编辑2:

这是我的包中源代码的修改片段,它使用相同类型的布局矩阵来定义图表中节点的位置,您可能会发现它们很有用:

gridLayout <- function(x)
{
    LmatX <- seq(-1,1,length=ncol(x))
    LmatY <- seq(1,-1,length=nrow(x))

    loc <- t(sapply(1:max(x),function(y)which(x==y,arr.ind=T)))
    layout <- cbind(LmatX[loc[,2]],LmatY[loc[,1]])
    return(layout)
}

此函数的作用是将指定网格中布局的矩阵(类似于layout())转换为具有x和y位置的两列布局。定义一个零的矩阵,并为每个节点整数从1到节点的总数(这是igraph ID + 1)。

例如,对于一个愚蠢的4节点图:

grid <- matrix(c(
    0,0,1,0,0,
    2,0,3,0,4),nrow=2,byrow=TRUE)

library("igraph")

g <- graph.adjacency(matrix(1,4,4))

plot(g,layout=gridLayout(L))

答案 1 :(得分:6)

如果您想自己分配节点位置,那么比上述方法更简单的方法是在数据表中添加标记为x和y的列,并在这些列中为各个节点添加x和y坐标。例如

library('igraph')
nodes <- c('a','b','c','d')
x <- c(0,1,2,3)
y <- c(0,1,2,3)
from <- c('a','b','c')
to <- c('b','c','d')
NodeList <- data.frame(nodes, x ,y)
EdgeList <- data.frame(from, to)
a<- graph_from_data_frame(vertices = NodeList, d= EdgeList, directed = FALSE)
plot(a)

enter image description here