【问题标题】:How to control the igraph plot layout with Fixed Positions?如何使用固定位置控制 igraph 绘图布局?
【发布时间】:2011-07-18 20:49:14
【问题描述】:

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

  1. 这是最好的 layout() 算法,还是我可以手动为每个节点分配位置>
  2. 如何确保这些节点在图中不会重叠(就像这里一样)?
  3. 能否将一个节点指定为“锚点”或起点?即,我可以将“C”设置为最顶部或最左侧的节点吗?

非常感谢!!

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)

【问题讨论】:

    标签: r igraph


    【解决方案1】:

    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:

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

    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))
    

    【讨论】:

    • 感谢您的提示!像这样设置位置将它们放在一起: l2
    • 2 年后这个答案对我有帮助:-)
    • Sacha,当我应用你的代码时,我得到了Error in ncol(x) : object 'L' not found。在plot(g,layout=gridLayout(L)) 行中可能有我无法理解的问题。
    【解决方案2】:

    如果您想自己分配节点位置,一种比上述简单的方法是在数据表中添加标记为 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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-01
      • 2011-02-20
      • 1970-01-01
      相关资源
      最近更新 更多