如何高效地可视化大规模图形网络

7
我用R模拟了一些图形网络数据(约10,000个观测值),并尝试使用R中的visNetwork库对其进行可视化。但是,数据非常杂乱,很难在视觉上进行分析(我知道在现实生活中,网络数据是使用图形查询语言进行分析的)。
目前有没有什么方法可以改善我创建的图形网络可视化(以便我可以探索一些彼此堆叠在一起的链接和节点)?
是否可以使用“networkD3”和“diagrammeR”等库来更好地可视化这个网络?
我已经附上了可重现的代码如下:
library(igraph)
library(dplyr)
library(visNetwork)

#create file from which to sample from
x5 <- sample(1:10000, 10000, replace=T)
#convert to data frame
x5 = as.data.frame(x5)

#create first file (take a random sample from the created file)
a = sample_n(x5, 9000)
#create second file (take a random sample from the created file)
b = sample_n(x5, 9000)

#combine
c = cbind(a,b)
#create dataframe
c = data.frame(c)
#rename column names
colnames(c) <- c("a","b")

graph <- graph.data.frame(c, directed=F)
graph <- simplify(graph)
graph

plot(graph)

library(visNetwork)
nodes <- data.frame(id = V(graph)$name, title = V(graph)$name)
nodes <- nodes[order(nodes$id, decreasing = F),]
edges <- get.data.frame(graph, what="edges")[1:2]

visNetwork(nodes, edges) %>%   visIgraphLayout(layout = "layout_with_fr") %>%
    visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE) %>% 
    visInteraction(navigationButtons = TRUE)

谢谢


你有看过ggiraph吗? - Roger-123
@Roger-123:感谢您的回复!我简要地看了一下 'ggraph',但我不确定它是否会使大型网络图(像我的)的可视化更好。您有什么建议吗? - stats_noob
这个回答解决了你的问题吗?如何在R中可视化一个大型网络? - majom
@majom:感谢您的回复!根据您提供的链接,我尝试使用NetworkD3,但无法使其正常工作。您有其他示例吗? - stats_noob
@majom:我会尝试这段代码:plot(simplify(g), vertex.size= 0.01,edge.arrow.size=0.001,vertex.label.cex = 0.75,vertex.label.color = "black" ,vertex.frame.color = adjustcolor("white", alpha.f = 0),vertex.color = adjustcolor("white", alpha.f = 0),edge.color=adjustcolor(1, alpha.f = 0.15),display.isolates=FALSE,vertex.label=ifelse(page_rank(g)$vector > 0.1 , "重要节点", NA)) - stats_noob
2个回答

10

根据OP的要求,我将之前回答可视化网络社区划分结果的方法应用到这个问题中。

该问题中的网络并没有使用特定的随机种子创建。 在这里,我指定了种子以便于重现结果。

## reproducible version of OP's network
library(igraph)
library(dplyr)

set.seed(1234)
#create file from which to sample from
x5 <- sample(1:10000, 10000, replace=T)
#convert to data frame
x5 = as.data.frame(x5)

#create first file (take a random sample from the created file)
a = sample_n(x5, 9000)
#create second file (take a random sample from the created file)
b = sample_n(x5, 9000)

#combine
c = cbind(a,b)
#create dataframe
c = data.frame(c)
#rename column names
colnames(c) <- c("a","b")

graph <- graph.data.frame(c, directed=F)
graph <- simplify(graph)

正如原帖所述,简单的图表很混乱。之前提到的答案将其分为两部分:

  1. 绘制所有小组件
  2. 绘制巨型组件

1. 小组件 不同的组件使用不同的颜色来区分它们。

## Visualize the small components separately
SmallV = which(components(graph)$membership != 1)
SmallComp = induced_subgraph(graph, SmallV)
LO_SC = layout_components(SmallComp, layout=layout_with_graphopt)
plot(SmallComp, layout=LO_SC, vertex.size=9, vertex.label.cex=0.8, 
    vertex.color=rainbow(18, alpha=0.6)[components(graph)$membership[SmallV]])

小组件

虽然这还有改进的空间,但这相当容易,不是问题的实质,所以我将把这个作为小组件的代表。

2. 巨型组件
仅仅绘制巨型组件仍然很难阅读。以下是两种改善显示效果的方法。这两种方法都依赖于对顶点进行分组。在本答案中,我将使用cluster_louvain来对节点进行分组,但您可以尝试其他社区检测方法。cluster_louvain产生了47个社区。

## Now try for the giant component
GiantV = which(components(graph)$membership == 1)
GiantComp = induced_subgraph(graph, GiantV)
GC_CL = cluster_louvain(GiantComp)
max(GC_CL$membership)
[1] 47

巨型方法1 - 分组顶点
创建一个强调社区的布局

GC_Grouped = GiantComp
E(GC_Grouped)$weight = 1
for(i in unique(membership(GC_CL))) {
    GroupV = which(membership(GC_CL) == i)
    GC_Grouped = add_edges(GC_Grouped, combn(GroupV, 2), attr=list(weight=6))
} 

set.seed(1234)
LO = layout_with_fr(GC_Grouped)
colors <- rainbow(max(membership(GC_CL)))
par(mar=c(0,0,0,0))
plot(GC_CL, GiantComp, layout=LO,
    vertex.size = 5, 
    vertex.color=colors[membership(GC_CL)], 
    vertex.label = NA, edge.width = 1)

分组顶点的巨型组件

这提供了一些见解,但是由于许多边缘使它有点难以阅读。

巨型方法2-收缩社区
将每个社区作为单个顶点绘制。顶点的大小反映了该社区中节点的数量。颜色代表该社区节点的度。

## Contract the communities in the giant component
CL.Comm = simplify(contract(GiantComp, membership(GC_CL)))
D = unname(degree(CL.Comm))

set.seed(1234)
par(mar=c(0,0,0,0))
plot(CL.Comm, vertex.size=sqrt(sizes(GC_CL)),
    vertex.label=1:max(membership(GC_CL)), vertex.cex = 0.8,
    vertex.color=round((D-29)/4)+1)

压缩社区的巨型组件

这样做更加简洁,但会失去社区内部结构。


1
我不理解第一个问题。在我看来,数据的规范是相同的,绘图对我来说也很好。对于Girvan-Newman算法和Louvain聚类算法之间没有强烈的偏好,但在另一个问题中,OP使用了Girvan-Newman,所以我继续使用它。Louvain更快。 :-) - G5W
1
关于visNetwork - 当然可以。只需按照问题中所做的操作,但是使用 SmallComp 替换 graph 即可。 - G5W
1
当我运行您的代码时,我得到了相同的错误,因为我没有小组件。所有顶点都在大组件中。 - G5W
第一个链接“社交网络方法介绍”非常好! - stats_noob
GiantV = which(components(graph)$membership == 1) ... 这意味着第一个组件,而不是组件大小=1? - user14644617
显示剩余15条评论

1

关于“现实生活”方面的提示。处理大型图形的最佳方法是:

  1. 通过某些度量过滤您正在使用的边缘,或
  2. 使用一些相关变量作为权重。

1
谢谢您的回复!您能推荐一些关于R语言的教程吗? - stats_noob
1
如果您不熟悉Tidyverse,我建议您使用Hadley的R4DS https://r4ds.had.co.nz。之后,您将很容易使用ggraph,您可以在以下链接中找到带有示例的vignette:https://github.com/thomasp85/ggraph - benjasast

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接