简体   繁体   English

如何在igraph&R中创建极坐标网络图(多个环)

[英]How to create a polar network graph (multiple rings) in igraph & R

I have a graph with <100 nodes, with several categories. 我有一个<100个节点的图表,有几个类别。 I would like the nodes belonging to one category to be in the center, with the other nodes arranged evenly in a circle around the outside - like a star graph, but with multiple nodes in the center. 我希望属于一个类别的节点位于中心,其他节点均匀地围绕外部排列成圆形 - 就像星形图,但中心有多个节点。 NodeXL calls this a polar graph (see: http://www.connectedaction.net/2013/03/03/how-to-plot-a-network-in-a-polar-layout-using-nodexl/ ) Given this data from the manual for graphs from dataframes: 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)

What if I want the females in the center and the males arranged in a circle around? 如果我希望中心的雌性和雄性围成一圈的话,该怎么办? I can divide up the graph and graph each separately, but I'm having trouble thinking through how to put them back together and am looking for another answer. 我可以单独划分图形和图形,但是我很难思考如何将它们重新组合在一起并且正在寻找另一个答案。

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)

Then I could assign them to V(gsubf)$x, V(gsubf)$y... but I'm struggling how to put it all back together. 然后我可以将它们分配给V(gsubf)$ x,V(gsubf)$ y ......但我正在努力将它们全部重新组合在一起。 There may be an easier way? 可能有一种更简单的方法? or maybe another package to do polar? 或者是另一个做极地的套餐?

I have responded to this question on the mailing list recently, but for sake of completeness I'll also include the answer here. 我最近在邮件列表上回答了这个问题,但为了完整起见,我还会在这里提供答案。

igraph layouts are simply matrices with 2 columns and one row for each vertex, so the easiest is probably if you generate such a matrix yourself. igraph布局就是每个顶点有2列和一行的矩阵,所以最简单的就是你自己生成这样一个矩阵。 If you want to place a vertex at radius r from the center with an angle of alpha (in radians), then you have to use the following formulae to figure out the X and Y coordinates: 如果要将半径为r的顶点放置在角度为alpha(以弧度为单位)的中心,则必须使用以下公式来计算X和Y坐标:

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

where the Y coordinate is negated only because the Y axis of the coordinate system of the screen is oriented from top to bottom. 其中Y坐标被否定的唯一原因是屏幕坐标系的Y轴从上到下。 So you can create a function like this in R: 所以你可以在R中创建这样的函数:

polar.layout <- function(radii, angles) {
    cbind(radii*cos(angles), -radii*sin(angles))        
}

The polar.layout function has to be called with two lists: one that specifies the radius of each vertex and one that specifies the angle of each vertex. 必须使用两个列表调用polar.layout函数:一个指定每个顶点的半径,另一个指定每个顶点的角度。 It will then return a matrix object that can be passed to plot() as follows: 然后它将返回一个矩阵对象,可以传递给plot() ,如下所示:

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

So all you need is two vectors: one for the radii and one for the angles. 所以你需要的只有两个向量:一个用于半径,一个用于角度。 You can construct these from the genders as follows: 你可以从性别构建这些如下:

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)

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

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