问题
Trying to plot a network with the ggraph
package and specify the coordinates of each node. While I can implement this with the igraph
package - I cannot do this with the ggraph
package.
# 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))
}
Here is the "old fashioned" way of plotting the igraph
object:
# 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")
Link to ggraph
documentation is here. Please also see GitHub repository for ggraph
for package installation instructions (need >R.3.3 version). Below is the ggraph plot that works (but I haven't specified the coordinates for each node):
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()
Here is my attempt to make the ggraph
plot with specified coordinates for each node. Following similar examples and earlier attempts in ggraph()
where coordinates of the nodes are passed onto the plot, I tried the following:
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))
Also tried using this function. It is difficult because there is not an example in the documentation.
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:
I don't believe it is the author's intention that you call layout_igraph_manual
directly. If you name the layout as "manual" you can pass in the arguments you need to layout the vertices manually. This got me what you are after, if I understand it correctly:
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()
According to the documentation it is important that your manual layout is a dataframe and contains the columns x
and y
. I have done this to the output of your coord()
function. You probably just want to update it to return the data in that form.
回答2:
You generally don't have to think about node coordinates when using ggraph - they are supplied automatically based on the chosen layout. If you want to calculate the layout yourself beforehand, just use the manual layout - check the documentation for layout_igraph_manual
回答3:
Thanks @ThomasP85 (wow! the developer for ggraph). In this instance I wanted to specify the coordinates for each of the nodes. I've tried layout_igraph_manual
, layout_
, add_layout_
and many others and did not seem to work.
What did work was this
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 if you can provide a working example with the code above using layout_igraph_manual
, it would be much appreciated.
来源:https://stackoverflow.com/questions/42048671/ggraph-network-plot-specify-node-coordinates