在图框中使用相同的坐标和相同的位置绘制两个 igraph 网络

Plot two igraph networks using the same coordinates and same placement in the plot frame

我正在尝试绘制一个随时间变化的网络。网络从一定数量的节点和边开始,每个时间步都会删除一些节点和边。

我希望能够绘制网络,以便每个节点都位于同一位置。但是,当我尝试这个时。有时即使彼此之间的关系相同,节点也会在图框中移动位置。

我正在将网络更改为 gif,因此即使是很小的更改也很烦人。我认为当大部分节点被删除时可能会发生变化,但我不确定。

下面的代码使用 ER 图对此进行了说明。

library(igraph); library(dplyr)

#generate random graph
set.seed(500)
RandomGraph <- sample_gnm(1000, 2500)

#name nodes
V(RandomGraph)$name <- paste0("Node", 1:1000)

#Get the coordinates of the Nodes
Coords <- layout_with_fr(RandomGraph) %>% 
  as_tibble %>%
    bind_cols(data_frame(names = names(V(RandomGraph))))

#Delete random vertices
deletevertex <-sample( V(RandomGraph)$name, 400)

RandomGraph2 <-delete.vertices(RandomGraph, deletevertex)

#get the coordinates of the remaining Nodes
  NetCoords <- data_frame(names = names(V(RandomGraph2))) %>%
    left_join(Coords, by= "names")

#plot both graphs

RandomGraph%>% 
  plot(.,vertex.size=.8, edge.arrow.size=.4, vertex.label = NA, layout = as.matrix(Coords[,1:2]))

RandomGraph2%>% 
  plot(.,vertex.size=.8, edge.arrow.size=.4, vertex.label = NA, layout = as.matrix(NetCoords[,2:3]))

#They nodes have the same relationship to each other but are not laid out in the same position in the frame

如您所见,这些图将节点放置在相对于彼此但不相对于框架的相同位置。

如何固定剧情位置

plot.igraph 默认重新缩放每个轴(x 和 y 上从 -1 到 +1)。

您只需将其关闭:rescale = F,然后明确设置适当的 xlimylim 值。

对于您的示例代码..

RandomGraph%>% 
  plot(.,vertex.size=.8, edge.arrow.size=.4, vertex.label = NA, layout = as.matrix(Coords[,1:2]),rescale=F,xlim=c(-25,30),ylim=c(-20,35))

RandomGraph2%>% 
  plot(.,vertex.size=.8, edge.arrow.size=.4, vertex.label = NA, layout = as.matrix(NetCoords[,2:3]),rescale=F,xlim=c(-25,30),ylim=c(-20,35))

问题是

identical(range(Coords[1]), range(NetCoords[2]))
# [1] FALSE

由于 igraph 在绘图之前将坐标归一化在 -1 和 1 之间的范围内,这导致 NetCoordsCoords 的坐标略有不同。我只是预先计算所有节点的归一化坐标:

coords_rescaled <- sapply(Coords[-3], function(x) -1+((x-min(x))*2)/diff(range(x)))
rownames(coords_rescaled) <- Coords$names

然后分配归一化坐标(或所需的子集)并设置rescale=FALSE(如@jul)已经建议:

par(mfrow=c(1,2), mar=c(1,.5,1,.5))
RandomGraph%>% 
  plot(.,edge.arrow.size=.4, layout = coords_rescaled, rescale=F);box()
RandomGraph2%>% 
  plot(.,edge.arrow.size=.4, layout = coords_rescaled[NetCoords$names, ], rescale=F);box()