2017-02-05 217 views
2

尝试使用ggraph程序包绘制网络并指定每个节点的坐标。虽然我可以通过igraph包实现这一点 - 但我无法使用ggraph包进行此操作。ggraph网络图:指定节点坐标

# reproducible example to generate a random graph 
library(igraph) 
g1 <- erdos.renyi.game(20, 1/2) 
plot(g1) 

# function to produce coordinates for each node in order of the node 
# degree (number of links per node) 
coord <- function(g){ 
    n.nod <- length(V(g)) 
    mat.c <- matrix(0, nrow = n.nod, ncol = 2) 
    deg <- degree(g) 
    uniq.deg <- unique(deg) 
    min.d <- min(deg); max.d<- max(deg) 
    spa <- 10/(max.d - min.d) # how much to increment 0 to 10 space along y-axis 

    divi.y.1 <- seq(from = min.d, to=max.d, by = 1) 
    divi.y.2 <- seq(from = 0, to=10, by = spa) # both have same length 

    ind.x <- c(); ind.x[1] = 0 
    for(x in 2:n.nod){ 
     ind.x[x] <- ind.x[x-1] + 0.1 
     if(ind.x[x] >= 10){ 
     ind.x[x] = ind.x[x-1] - 0.1 
     } 
    } 
d1 <- data.frame(divi.y.1, divi.y.2) 

# plotting space of grid is (0,0), (0, 10), (10, 10), (10, 0) 
for(i in 1:n.nod){ 
    # y-axis in order 
    inD <- which(d1$divi.y.1 == deg[i]) 
    mat.c[i, 2] <- d1[inD,2] 
} 
mat.c[, 1] <- ind.x 
return(data.frame(mat.c)) 
} 

这里是绘制igraph对象的 “老土” 的方式:

# plot igraph object - the old fashion way 
x11() 
plot(g1, layout = coord(g1), rescale = T, frame=T, 
vertex.frame.color = "black", edge.color = "lightsteelblue", 
edge.width = 1, vertex.label.cex = 1, 
vertex.label.color = "black", 
main = "Nodes in order of degree: top have more links, bottom fewer links") 

链接到ggraph文档here。有关软件包安装说明(需要> R.3.3版本),请参阅ggraph的GitHub存储库。下面是GGRAPH情节的作品(但我没有指定每个节点的坐标):

library(ggraph) 
V(g1)$NaMe <- seq(1:20) 

x11() 
    ggraph(g1, 'igraph', algorithm = 'kk') + 
    geom_edge_link(colour = "black", alpha = 0.8, show.legend = F) + 
    geom_node_label(aes(label = NaMe)) + ggtitle("ggraph plot: How to allocate coordinate for each node?") + 
    ggforce::theme_no_axes() 

这是我试图使ggraph情节为每个节点指定的坐标。继在节点的坐标传递到情节ggraph()类似的例子和较早尝试,我试过如下:

g <- make_ring(10) + make_full_graph(5) 
coords <- layout_(g, as_star()) 
plot(g, layout = coords) 
# try to replicate this example: 
coords2 <- add_layout_(g1, coord(g1)) 

使用this function也试过。这很难,因为文档中没有例子。

Lay <- layout_igraph_manual(g1, coord(g1)) 
Lay <- layout_igraph_igraph(g1, coord(g1)) 

x11() 
ggraph(g1, 'igraph', algorithm = 'kk') + add_layout_(Lay) + 
# layout_igraph_circlepack() + 
geom_edge_link(colour = "black", alpha = 0.8, show.legend = F) + 
geom_node_label(aes(label = NaMe)) + ggtitle("ggraph plot: Cannot allocate coordinate for each node") + 
ggforce::theme_no_axes() 

回答

1

你一般没有想到用GGRAPH当有关节点的坐标 - 他们提供自动根据所选择的布局。如果你想事先自己计算布局,只需使用手动布局 - 检查文档layout_igraph_manual

1

谢谢@ ThomasP85(哇!ggraph的开发人员)。在这种情况下,我想指定每个节点的坐标。我试过layout_igraph_manuallayout_add_layout_和其他许多人,似乎没有工作。

什么做的工作是这样的

co2<- data.frame(coord(g1)) # my mistake above, the output of coord() should be a matrix 
colnames(co2)<- c("x", "y") 
Lay<- createLayout(g1, layout = "nicely") # try any layout 
Lay$x<- co2$x # <== now overwrite their coordinates 
Lay$y<- co2$y 


x11() # <==== this is ggraph version of the igraph plot above 
ggraph(graph=g1, data=Lay) + 
geom_edge_link(colour = "black", alpha = 0.5, show.legend = F) + 
geom_node_label(aes(label = NaMe)) + ggtitle("Nodes with higher degree at top, lower degree nodes at the bottom") + 
ggforce::theme_no_axes() 

@ ThomasP85如果你能提供与上述使用layout_igraph_manual代码工作的例子,这将是大加赞赏。

1

我不相信这是作者的意图,你直接拨打layout_igraph_manual。如果您将布局命名为“手动”,则可以传递手动布局顶点所需的参数。这让我你是什么之后,如果我理解正确:

coords <- coord(g1) 
names(coords) <- c("x","y") 
coords <- as.data.frame(coords) 

ggraph(g1, layout = "manual", circular = FALSE, node.positions = coords)+ 
    geom_edge_link(colour = "black", alpha = 0.8, show.legend = F) + 
    geom_node_label(aes(label = NaMe)) + ggtitle("ggraph plot: How to allocate coordinate for each node?") + 
    ggforce::theme_no_axes() 

根据该文件,重要的是你的手工布局是一个数据框,包含列xy。我已经完成了你的coord()函数的输出。您可能只想更新它以返回该表单中的数据。