如何在igraph&amp ;;中创建极地网络图(多个环) [R

时间:2015-03-05 01:04:07

标签: r igraph

我有一个包含< 100个节点的图表,有几个类别。我希望属于一个类别的节点位于中心,其他节点均匀地围绕外部排列成圆形 - 就像星形图,但中心有多个节点。 NodeXL称之为极坐标图(参见:http://www.connectedaction.net/2013/03/03/how-to-plot-a-network-in-a-polar-layout-using-nodexl/) 根据数据框图表手册中的数据:

actors<-data.frame(name=c("Alice", "Bob", "Cecil", "David",
                        "Esmeralda"),
                 age=c(48,33,45,34,21),
                 gender=c("F","M","F","M","F"))
relations <- data.frame(from=c("Bob", "Cecil", "Cecil", "David",
                           "David", "Esmeralda"),
                    to=c("Alice", "Bob", "Alice", "Alice", "Bob", "Alice"),
                    same.dept=c(FALSE,FALSE,TRUE,FALSE,FALSE,TRUE),
                    friendship=c(4,5,5,2,1,1), advice=c(4,5,5,4,2,3))
g <- graph.data.frame(relations, directed=TRUE, vertices=actors)

如果我希望中间的雌性和雄性排成一圈怎么办? 我可以单独划分图形和图形,但是我无法思考如何将它们重新组合在一起并且正在寻找另一个答案。

gsubf<-induced.subgraph(g,V(g)$gender=="F")
gsubm<-induced.subgraph(g,V(g)$gender=="M")
gsubfcoords<-layout.fruchterman.reingold(gsubf, xlim=c(-2,2), ylim=c(-2,2))
gsubmcoords<-layout.circle(gsubm)

然后我可以将它们分配给V(gsubf)$ x,V(gsubf)$ y ......但我正在努力将它们全部重新组合在一起。可能有一种更简单的方法?或者是另一个做极地的方案?

1 个答案:

答案 0 :(得分:3)

我最近在邮件列表上回答了这个问题,但为了完整起见,我还会在这里提供答案。

igraph布局是简单的矩阵,每个顶点有2列和1行, 所以最容易的就是你自己生成这样一个矩阵。如果你想 从中心放置一个半径为r的顶点,角度为alpha(in 弧度),然后你必须使用下面的公式来找出X和 Y坐标:

X = r * cos(alpha)
Y = -r * sin(alpha)

其中Y坐标仅因坐标的Y轴而被否定 屏幕系统从上到下定向。所以你可以在R:

中创建这样的函数
polar.layout <- function(radii, angles) {
    cbind(radii*cos(angles), -radii*sin(angles))        
}

必须使用两个列表调用polar.layout函数:一个指定 每个顶点的半径和指定每个顶点的角度的半径。它 然后将返回一个矩阵对象,该对象可以传递给plot(),如下所示:

layout <- polar.layout(radii, angles)
plot(graph, layout=layout)

所以你需要的只有两个向量:一个用于半径,一个用于角度。您可以按性别从性别构建这些:

males <- which(V(g)$gender == "M")
females <- which(V(g)$gender == "F")
radii <- ifelse(V(g)$gender == "F", 1, 2)
angles <- rep.int(0, vcount(g))
angles[males] <- (1:length(males)-1) * 2 * pi / length(males)
angles[females] <- (1:length(females)-1) * 2 * pi / length(females)
layout <- polar.layout(radii, angles)
plot(g, layout=layout)