可视化数据时,网络可以很好展示各个节点之间的关系以及关系的重要性。网络中存在大量的节点和边,因此绘制一个好的网络会有助于信息的解读。networkD3可以自定义网络的各种特征,绘制一个优美的动态网络。
#1. 安装
install.packages("networkD3")
#2. 使用
networkD3 绘图基于JavaScript,所以索引是从0开始的;R中从1开始。
可以使用R包 igraph构建网络绘制需要的数据,使用igraph_to_networkD3
函数将数据转换成networkD3 要求格式的输入数据。
##2.1 simpleNetwork
simpleNetwork(Data, Source = 1, Target = 2, height = NULL, width = NULL,
linkDistance = 50, charge = -30, fontSize = 7, fontFamily = "serif",
linkColour = "#666", nodeColour = "#3182bd", opacity = 0.6, zoom = F)
simpleNetwork是networkD3的基础函数,可以快速出图。
绘制网络
# Load package
library(networkD3)
# Create fake data
src <- c("A", "A", "A", "A",
"B", "B", "C", "C", "D")
target <- c("B", "C", "D", "J",
"E", "F", "G", "H", "I")
networkData <- data.frame(src, target)
# Plot
simpleNetwork(networkData)
##2.2 forceNetwork
forceNetwork有更多的参数,调整参数可以绘制更复杂的网络图。
forceNetwork(Links, Nodes, Source, Target, Value, NodeID, Nodesize, Group,
height = NULL, width = NULL,
colourScale = JS("d3.scaleOrdinal(d3.schemeCategory20);"), fontSize = 7,
fontFamily = "serif", linkDistance = 50,
linkWidth = JS("function(d) { return Math.sqrt(d.value); }"),
radiusCalculation = JS(" Math.sqrt(d.nodesize)+6"), charge = -30,
linkColour = "#666", opacity = 0.6, zoom = FALSE, legend = FALSE,
arrows = FALSE, bounded = FALSE, opacityNoHover = 0,
clickAction = NULL)
Links:边的数据集
Nodes:节点数据集
Source:边的数据集中列名,指定边起始点
Target:边的数据集中列名,指定边终点
Value:边宽度的数据,一般时边权重
NodeID:节点数据集中节点的列
Nodesize:节点大小
Group:节点的分组
height = NULL:网络高度
width = NULL:网络宽度
fontFamily = "serif":字体
linkColour = "#666":边的颜色
opacity = 0.6:节点透明度
zoom = FALSE:图是否可以缩放
legend = FALSE:是否展示图例
arrows = FALSE:边是否有箭头
bounded = FALSE:图是否显示边界
opacityNoHover = 0:鼠标选择某个节点时,其他节点的透明度
clickAction = NULL:JavaScript语言表达式,定义当节点被点击时,需要的操作
绘制网络
forceNetwork的数据格式比较麻烦; 尤其是参数Nodes;建议大家使用igraph包 igraph_to_networkD3()网络图所需数据将转换为networkD3数据格式。本文见#3. 与igraph交互部分。
# Create fake data
src <- c("A", "A", "A", "A",
"B", "B", "C", "C", "D")
target <- c("B", "C", "D", "J",
"E", "F", "G", "H", "I")
networkData <- data.frame(src, target)
nodeData <- data.frame(name=unique(c(src, target)),
group= c(rep(1,5),rep(2,5)))
linkData <- data.frame(source = (match(networkData$src, nodeData$name)-1),
target = (match(networkData$target, nodeData$name)-1),
value = rnorm(length(src), mean=0, sd=1))
forceNetwork(
Links = linkData,
Nodes = nodeData,
Source = "source",
Target = "target",
Value = "value",
NodeID = "name",Group = "group")
# Load data
data(MisLinks)
data(MisNodes)
# Plot
forceNetwork(Links = MisLinks, Nodes = MisNodes,
Source = "source", Target = "target",
Value = "value", NodeID = "name",
Group = "group", opacity = 0.8)
# with a simple click action - make the circles bigger when clicked
MyClickScript <-
' d3.select(this).select("circle").transition()
.duration(750)
.attr("r", 30)'
forceNetwork(Links = MisLinks, Nodes = MisNodes, Source = "source",
Target = "target", Value = "value", NodeID = "name",
Group = "group", opacity = 1, zoom = F, bounded = T,
clickAction = MyClickScript)
MyClickScript <- 'alert("You clicked " + d.name + " which is in row " + (d.index + 1) +
" of your original R data frame");'
forceNetwork(Links = MisLinks, Nodes = MisNodes, Source = "source",
Target = "target", Value = "value", NodeID = "name",
Group = "group", opacity = 1, zoom = F, bounded = T,
clickAction = MyClickScript)
# Create graph with legend and varying radius
forceNetwork(Links = MisLinks, Nodes = MisNodes, Source = "source",
Target = "target", Value = "value", NodeID = "name",
Nodesize = 'size', radiusCalculation = "d.nodesize",
Group = "group", opacity = 1, legend = T, bounded = F)
##2.3 桑基图
# Load energy projection data
URL <- paste0(
"https://cdn.rawgit.com/christophergandrud/networkD3/",
"master/JSONdata/energy.json")
Energy <- jsonlite::fromJSON(URL)
# Plot
sankeyNetwork(Links = Energy$links, Nodes = Energy$nodes, Source = "source",
Target = "target", Value = "value", NodeID = "name",
units = "TWh", fontSize = 12, nodeWidth = 30)
##2.4 放射状网络
URL <- paste0(
"https://cdn.rawgit.com/christophergandrud/networkD3/",
"master/JSONdata//flare.json")
## Convert to list format
Flare <- jsonlite::fromJSON(URL, simplifyDataFrame = FALSE)
# Use subset of data for more readable diagram
Flare$children = Flare$children[1:3]
radialNetwork(List = Flare, fontSize = 10, opacity = 0.9)
diagonalNetwork(List = Flare, fontSize = 10, opacity = 0.9)
##2.5 树状图
hc <- hclust(dist(USArrests), "ave")
dendroNetwork(hc, height = 600)
#3. 与igraph交互
调用 igraph 包创建网络图所需数据,igraph_to_networkD3函数转换数据格式,networkD3绘制图。
# Load igraph
library(igraph)
# Use igraph to make the graph and find membership
karate <- make_graph("Zachary")
wc <- cluster_walktrap(karate)
members <- membership(wc)
# Convert to object suitable for networkD3
karate_d3 <- igraph_to_networkD3(karate, group = members)
# Create force directed network plot
forceNetwork(Links = karate_d3$links, Nodes = karate_d3$nodes,
Source = 'source', Target = 'target',
NodeID = 'name', Group = 'group')
#4. 动态网络图输出
##4.1 保存成HTML
library(magrittr)
simpleNetwork(networkData) %>%
saveNetwork(file = 'Net1.html')
##4.2 内置于RMarkdown
参考networkD3
##4.3 内置于Shiny
在server.R调用render*Network(*可以是 Simple
,Force
, Sankey
)
output$force <- renderForceNetwork({
forceNetwork(Links = MisLinks, Nodes = MisNodes,
Source = "source", Target = "target",
Value = "value", NodeID = "name",
Group = "group", opacity = input$opacity)
})
在app.R文件中调用*NetworkOutput(*可以是 Simple
,Force
, Sankey
)
forceNetworkOutput("force")
shiny例子:networkD3-shiny-example
shiny::runGitHub('christophergandrud/networkD3-shiny-example')
#5. 参考:
networkD3 :D3 JavaScript Network Graphs from R
networkD3 github
系列文章:
R语言进行网络分析的基础包 igraph
networkD3 绘制动态网络
网络-visNetwork包绘制炫酷的动态网络图
网络-调用R包构建交互式网络可视化的Shiny App