json数据可视化工具 json树状图可视化_d3



静态的网络可视化往往难以展示网络的细节,比如说,虽然我们可以用颜色、符号或者尺寸大小等等方式来展示节点的不同属性,不重要的节点往往会淹没在大量的节点和边之中,具体情况无从了解;再比如,我们可以标示出某个节点及其相邻节点,但对于每个节点进行这样的操作,就会力不从心;这些涉及网络细节的操作,需要具有交互功能的网络可视化来完成。R中有多个可以实现交互功能的网络可视化包,本文介绍其中之一:networkD3包。

networkD3包是基于著名的Javascript可视化库d3.js构建的,可以生成htmlwidgets框架的d3网络图。与不再开发的前作d3network包相比,采用了htmlwidgets框架的networkD3包,简化了导出图形的语法,并且改进了与RStudio’s Viewer Pane, RMarkdown和Shiny web apps的集成。

networkD3包主要优点是操作简单、图形美观,可以和igraph对象进行交互,也可以用在RMarkdown文档和Shiny的网络应用当中。缺点就是功能相对单一,而且上一次更新还是在2017年。

1、使用networkD3绘制网络图

先从最简单的函数simpleNetwork()开始,只需要一个边列表(包含每条边起点与终点的数据框),就可以使用simpleNetwork()绘制网络。我们选用的数据集是之前使用过的《权游》第3季的角色互动数据:


library(networkD3)
library(igraph)
library(tidyverse)

url<-"https://www.macalester.edu/~abeverid/data/stormofswords.csv"
thrones<-read_csv(url)
save(thrones,file="thrones.csv")

###节点列表
name<-data.frame(c(thrones$Source,thrones$Target))
nodes<-name%>%
distinct()
colnames(nodes)<-"label"

###边列表
edges<-thrones

###绘制网络
simpleNetwork(edges,Source=1,Target=2,fontSize=12)


json数据可视化工具 json树状图可视化_json数据可视化工具_02

图1


图1就是一个基本的d3网络图。其中edges指定了绘图所用的数据,就是一个包含着三列的边列表(每条边的起点、终点和权重)。Source指定边的起点列,Target指定边的终点列,fontSize指定了节点名称的大小。生成的图像会在浏览器中打开,悬停在图上某个节点,就会显示它的边和相邻节点。如果你想知道一团节点中的某一个是哪一位角色,可以用鼠标把它拖拽出来,整个网络也会随之进行相应的变形。

如果需要绘制更复杂的网络图,我们需要先建立一个igraph对象,在这个对象上进行一些网络性质的操作和计算,然后使用igraph_to_networkD3()函数将这个igraph对象转换成适用于networkD3的列表。然而,用于绘制复杂网络图的函数只有forceNetwork()这一个,可以生成力导向图。

我们继续前面的例子,生成一个igraph对象net_pc,在此基础上,计算节点的度用于表示节点的大小,检测网络的社区对节点进行分组。然后,转换为networkD3所需的图列表:


###建立igraph对象
net_pc<-graph_from_data_frame(
d=edges,vertices=nodes,
directed=FALSE)

###计算节点和边的一些性质             
deg<-degree(net_pc)
V(net_pc)$size<-deg/5
E(net_pc)$width<-E(net_pc)$Weight/10

###社区识别
eb<-cluster_infomap(net_pc)
###由社区指定分组
groups<-membership(eb)

###转换为图列表
net_pcd3<-igraph_to_networkD3(net_pc,group=groups)


这个图列表是这样的:


> str(net_pcd3)
List of 2
 $ links:'data.frame':  352 obs. of  2 variables:
  ..$ source: num [1:352] 16 7 4 6 16 27 53 49 33 4 ...
  ..$ target: num [1:352] 86 72 72 74 74 74 74 74 74 7 ...
 $ nodes:'data.frame':  107 obs. of  2 variables:
  ..$ name : Factor w/ 107 levels "Aegon","Aemon",..: 2 3 4 5 7 8 10 11 13 14 ...
  ..$ group: num [1:107] 2 1 2 1 5 1 4 5 6 3 ...


边列表包括了边的起点和终点,节点列表包括了节点名称和分组。

边和节点更多的性质需要我们自己添加。然后,使用forceNetwork()进行绘图:


net_pcd3$links$value<-E(net_pc)$width
net_pcd3$nodes$Nodesize<-V(net_pc)$size

###指定点击事件
script <- 'alert("row: "     + (d.index + 1) + 
                 ", name: "  + d.name + 
                 ", group: " + d.group + 
                 ", size: "  + d.nodesize )'
###生成网络
network<-forceNetwork(Links=net_pcd3$links,Nodes=net_pcd3$nodes,
             Source="source",Target="target",Value="value",fontSize=20,
             Nodesize="Nodesize",NodeID="name",Group="group",
             opacity = 1,clickAction = script
)
###保存网络
saveNetwork(network,file="throne.html",selfcontained=F)


json数据可视化工具 json树状图可视化_json数据可视化工具_03

图2

forceNetwork()的大多数参数是关于节点和边的性质指定,其中value对应于边的宽度,opacity指定了透明度。clickAction参数是networkD3最大的亮点,通过它可以定义相应的鼠标点击事件。在这里,我们定义的点击事件script会显示对节点性质的描述。如果对Javascript熟悉的话,还可以定义更复杂的点击事件,如弹出对话框,加入搜索框等。

最后,使用saveNetwork函数将生成的网络保存成了一个HTML文件。在Rstudio中,还可以将生成的网络保存成PNG文件。

2、使用networkD3绘制广义的网络图

networkD3还可以绘制几种广义的网络图,如桑基图、径向树状图和聚类谱系图。

桑基图

我们使用的数据文件energy.csv来自d3网站:https://observablehq.com/@d3/sankey-diagram。这个数据集展示了能源的转换和传输情况。按照先建立igraph对象,再转换为networkD3列表的方式绘制:


energy<-read_csv('~/energy.csv')###修改成你的路径

####建立节点列表边列表
###节点列表
name<-data.frame(c(energy$source,energy$target))
nodes<-name%>%
distinct()
colnames(nodes)<-"label"
###边列表
edges<-as.data.frame(energy)

energy_igraph<-graph_from_data_frame(
d=edges,vertices=nodes,
directed=T)###桑基图是有指向的


energy_d3<-igraph_to_networkD3(energy_igraph)

sankeyNetwork(Links = energy_d3$links, Nodes = energy_d3$nodes, Source = 'source',
              Target = 'target', Value = 'value', NodeID = 'name',fontSize = 20, nodeWidth =25)


json数据可视化工具 json树状图可视化_d3_04

图3

可以看到绘制桑基图的函数sankeyNetwork()与力导向图函数forceNetwork()的使用方式是一致的。

径向树图

使用的数据文件flare-2.json反映了一个叫做 flare的可视化库的层次结构,来自d3.js网站https://observablehq.com/@d3/radial-tidy-tree。这个json文件需要使用jsonlite包的fromJSON函数进行读取。径向树图是一种表示分层节点的连接图,networkD3提供了两种形式的径向树图函数:radialNetwork(图4)和diagonalNetwork(图5):


library(jsonlite)
URL<-'~/flare-2.json'###修改成你的路径

flare <- fromJSON(URL, simplifyDataFrame = FALSE)

flare$children<-flare$children[1:3]

radialNetwork(List = flare, fontSize = 10, opacity = 0.9)
diagonalNetwork(List = flare, fontSize = 10, opacity = 0.9)


json数据可视化工具 json树状图可视化_json_05

图4

json数据可视化工具 json树状图可视化_d3_06

图5