在 ggnet 中更改点绘图顺序

Change point plotting order in ggnet

我正在处理一个大型网络,也希望突出显示某些节点​​。我希望这些节点绘制在密集网络之上。它们目前由某种颜色标识。这是一些简单的示例代码。

library(network)
library(GGally)

# make a random network
x <- c(0,1,0,1,1,1,0,1,0,1,0,1)
seed <- c(10,25,40,34,1,35,6,3,14,5,23,3)
net <- data.frame(matrix(nrow = 12, ncol = 12))
for (i in 1:12) {
  set.seed(seed[i])
  net[i] <- sample(x)
}

#plot it with two colors
plot = as.network(net,
                 directed = FALSE,
                 ignore.eval = FALSE,
                 names.eval = 'R_val')

color <- c("yes","yes","no","no","no","no","no","no","no","no","no","no")
final <- ggnet2(net,size = 25,color = color,label = TRUE)

我真的夸大了这里的点大小以使它们重叠。有没有办法让“是”点始终绘制在“否”点之上?

编辑:为清楚起见添加了“标签”。

是的,有!您的 color 向量首先表示“是”,然后表示“否”,这似乎决定了绘图顺序。假设您有多个“是”或“否”,您可以尝试将 color 向量转换为一个因子并设置水平。然后你可以对你的“是”和“否”的顺序进行排序:

color <- c("yes","yes","no","no","no","no","no","no","no","no","no","no")
factor_color <- sort(factor(color, levels = c("no", "yes")))
ggnet2(net, size = 100, color = factor_color)

编辑 1

根据你的评论,我想不出一个(更)优雅的解决方案,但这对我有用:

#plot it with two colors
plot = as.network(net,
                  directed = FALSE,
                  ignore.eval = FALSE,
                  names.eval = 'R_val')

color <- c("yes","yes","no","no","no","no","no","no","no","no","no","no")
final <- ggnet2(net,size = 100, color = color, label = TRUE)
final_build <- ggplot2::ggplot_build(final)

# Extract the geom_point data and find which elements have 'yes'
yes_index <- which(color == "yes")
label_data <- final_build$data[[2]]
yes_coordinates_label <- cbind(label_data[yes_index,], label = names(net)[yes_index])

final + 
  geom_point(data = yes_coordinates_label, aes(x = x, y = y),
             size = 100, color = first(yes_coordinates_label$colour)) +
  geom_text(data = yes_coordinates_label, aes(x = x, y = y, label = label))

想法是再次用 geom_point() 绘制点,但仅针对“是”的点。

编辑 2

我忍不住又想到了另一种解决方案,没有重新绘制点。可以使用 ggplot_build() 检索绘图信息,然后重新排列绘制点的层次结构;首先绘制的数据点。因此,执行以下操作将起作用:

library(tidyverse)

# Find the index of the GeomPoint layer
geom_types <- final$layers %>% map("geom") %>% map(class)
GeomPoint_ind <- which(sapply(geom_types, function(x) "GeomPoint" %in% x))

# Retrieve plot information
final_build <- ggplot2::ggplot_build(final)
df <- final_build$data[[GeomPoint_ind]]

# Set the indices which you would like to have on top and modify the ggplot_build object. 
yes_index <- which(color == "yes")
final_build$data[[2]] <- rbind(df[-yes_index,], df[yes_index,])

# Convert to plot object and plot
new_final <- ggplot_gtable(final_build)
plot(new_final)