R - 闪亮应用程序中 visNetwork 与 networkd3 的最先进性能 (2017)
R - state of the art performance of visNetwork vs networkd3 in a Shiny app (2017)
我想根据中心性为 "large" 图(少于 500 个节点)上的顶点着色,并允许用户在单击事件时删除边或顶点。删除顶点或边时,将在图形上重新计算新的中心性分数,并再次渲染边和顶点的颜色。
我一直在查看 visNetwork and networkD3 R packages. This 2015 blog post 提到 visNetwork 的功能优于 networkD3,但我读过几个 SO 问题,其中提到 networkD3 如何更改和扩展其功能。
这两个包哪个更容易满足我的要求?
你知道,对于我正在开始的项目,我需要自己了解这一点,真正了解的唯一方法就是尝试一下。
所以我写了一个应用程序。
library(shiny)
library(ggplot2)
library(visNetwork)
library(networkD3)
library(RColorBrewer)
set.seed(123)
u <- shinyUI(fluidPage(
titlePanel("Network Library Comparison"),
sidebarLayout(position = "left",
sidebarPanel( h2("Parameters"),
selectInput("mode","Network:",c("MisNodes","Random","Circular"),"Random"),
numericInput("nnodes","Nodes:",10,1,10000,1),
sliderInput("edgefak","Edge Factor:",0,10,2,step=0.1),
numericInput("ngroups","Groups:",5,1,11,1),
actionButton("gennet","Generate"),
textOutput("networkstat")
),
mainPanel(h2("Network Plots"),
tabsetPanel(
tabPanel("networkD3", forceNetworkOutput("networkD3",,height="500px"),
style = "background-color: #eeeeee;"),
tabPanel("visNetwork",visNetworkOutput("visnetwork",height="500px"),
style = "background-color: #eeeeee;")
)
)
)
))
#MisLinks and MisNodes are a standard example from networkD3
data(MisLinks)
data(MisNodes)
fmtarrstr <- function(arr){
# first add ' surrounding every element
qarr <- sprintf("'%s'",as.character(arr))
# now concactinate them together seperated with ,
paste(qarr,collapse=",")
}
clrpal <- brewer.pal(n=11,name="Spectral")
clrscale <- sprintf('d3.scaleOrdinal() .domain([%s]) .range([%s]);',
fmtarrstr(1:11),fmtarrstr(clrpal))
s <- shinyServer(function(input, output){
net <- reactiveValues(nodes=NULL,edges=NULL,groups=NULL)
observeEvent(input$gennet,{
print("regenerating network")
mode <- input$mode
nn <- input$nnodes
ng <- input$ngroups
edgefak <- input$edgefak
if(mode=="MisNodes"){
nodes <- data.frame(id = 0:(nrow(MisNodes)-1),
label=MisNodes$name,
title=MisNodes$name,
group=MisNodes$group,
color=clrpal[MisNodes$group+1],
size=MisNodes$size)
edges <- data.frame(from = MisLinks$source, to = MisLinks$target)
net$groups <- data.frame(id=1:11,colors<-clrpal[1:11])
} else if(mode=="Random"){
nodes <- data.frame(id = 0:(nn-1),
label=0:(nn-1),
title=0:(nn-1),
group=sample(0:(ng-1),nn,replace=T),
size=10)
nodes$color <- clrpal[nodes$group+1]
nedge <- trunc(nn*edgefak)
frvek <- sample(0:(nn-1),nedge,replace=T)
tovek <- sample(0:(nn-1),nedge,replace=T)
edges <- data.frame(from = frvek, to = tovek)
net$groups <- data.frame(id=1:ng,colors<-clrpal[1:ng])
} else if(mode=="Circular"){
nodes <- data.frame(id = 0:(nn-1),
label=0:(nn-1),
title=0:(nn-1),
group=sample(0:(ng-1),nn,replace=T),
size=10)
nodes$color <- clrpal[nodes$group+1]
nedge <- nn
frvek <- 0:(nn-1)
tovek <- c(1:(nn-1),0)
edges <- data.frame(from = frvek, to = tovek)
net$groups <- data.frame(id=1:ng,colors<-clrpal[1:ng])
}
net$nodes <- nodes
net$edges <- edges
net$groups <- data.frame(id=1:ng,colors<-clrpal[1:ng])
})
output$visnetwork <- renderVisNetwork({
req(net$edges)
netout <- visNetwork(net$nodes,net$edges)
netout
})
output$networkD3 <- renderForceNetwork({
req(net$edges)
netout <- forceNetwork(
Links = net$edges, Nodes = net$nodes,
Source = "from", Target = "to",
NodeID = "label", Nodesize="size",
Group="group",opacity=1.0, zoom=T, fontSize = 12,
colourScale = JS(clrscale))
netout
})
output$networkstat <- renderText({
sprintf("\nNodes:%d Edges:%d Groups:%d",
nrow(net$nodes),nrow(net$edges),nrow(net$groups))
})
})
shinyApp(u,s)
看起来像这样:
总而言之,我会说它们都有优点和缺点,总的来说我认为 visNetwork
更容易使用,并且那些样条曲线看起来更酷,但是 networkD3
肯定快得多更大网络的初始化。 visNetwork
在 200 个节点的初始化过程中已经很痛苦了,尽管一旦绘制就很好了。
备注:
networkD3
鼠标缩放仅适用于真实浏览器(我使用的是 Chrome)。我无法让它在 R-Studio 浏览器中运行。快把我逼疯了。
- 就此而言,Chrome 中的一切速度明显快于 R-Studio 浏览器。在真实的浏览器中进行基准测试和实际工作。
我想根据中心性为 "large" 图(少于 500 个节点)上的顶点着色,并允许用户在单击事件时删除边或顶点。删除顶点或边时,将在图形上重新计算新的中心性分数,并再次渲染边和顶点的颜色。
我一直在查看 visNetwork and networkD3 R packages. This 2015 blog post 提到 visNetwork 的功能优于 networkD3,但我读过几个 SO 问题,其中提到 networkD3 如何更改和扩展其功能。
这两个包哪个更容易满足我的要求?
你知道,对于我正在开始的项目,我需要自己了解这一点,真正了解的唯一方法就是尝试一下。
所以我写了一个应用程序。
library(shiny)
library(ggplot2)
library(visNetwork)
library(networkD3)
library(RColorBrewer)
set.seed(123)
u <- shinyUI(fluidPage(
titlePanel("Network Library Comparison"),
sidebarLayout(position = "left",
sidebarPanel( h2("Parameters"),
selectInput("mode","Network:",c("MisNodes","Random","Circular"),"Random"),
numericInput("nnodes","Nodes:",10,1,10000,1),
sliderInput("edgefak","Edge Factor:",0,10,2,step=0.1),
numericInput("ngroups","Groups:",5,1,11,1),
actionButton("gennet","Generate"),
textOutput("networkstat")
),
mainPanel(h2("Network Plots"),
tabsetPanel(
tabPanel("networkD3", forceNetworkOutput("networkD3",,height="500px"),
style = "background-color: #eeeeee;"),
tabPanel("visNetwork",visNetworkOutput("visnetwork",height="500px"),
style = "background-color: #eeeeee;")
)
)
)
))
#MisLinks and MisNodes are a standard example from networkD3
data(MisLinks)
data(MisNodes)
fmtarrstr <- function(arr){
# first add ' surrounding every element
qarr <- sprintf("'%s'",as.character(arr))
# now concactinate them together seperated with ,
paste(qarr,collapse=",")
}
clrpal <- brewer.pal(n=11,name="Spectral")
clrscale <- sprintf('d3.scaleOrdinal() .domain([%s]) .range([%s]);',
fmtarrstr(1:11),fmtarrstr(clrpal))
s <- shinyServer(function(input, output){
net <- reactiveValues(nodes=NULL,edges=NULL,groups=NULL)
observeEvent(input$gennet,{
print("regenerating network")
mode <- input$mode
nn <- input$nnodes
ng <- input$ngroups
edgefak <- input$edgefak
if(mode=="MisNodes"){
nodes <- data.frame(id = 0:(nrow(MisNodes)-1),
label=MisNodes$name,
title=MisNodes$name,
group=MisNodes$group,
color=clrpal[MisNodes$group+1],
size=MisNodes$size)
edges <- data.frame(from = MisLinks$source, to = MisLinks$target)
net$groups <- data.frame(id=1:11,colors<-clrpal[1:11])
} else if(mode=="Random"){
nodes <- data.frame(id = 0:(nn-1),
label=0:(nn-1),
title=0:(nn-1),
group=sample(0:(ng-1),nn,replace=T),
size=10)
nodes$color <- clrpal[nodes$group+1]
nedge <- trunc(nn*edgefak)
frvek <- sample(0:(nn-1),nedge,replace=T)
tovek <- sample(0:(nn-1),nedge,replace=T)
edges <- data.frame(from = frvek, to = tovek)
net$groups <- data.frame(id=1:ng,colors<-clrpal[1:ng])
} else if(mode=="Circular"){
nodes <- data.frame(id = 0:(nn-1),
label=0:(nn-1),
title=0:(nn-1),
group=sample(0:(ng-1),nn,replace=T),
size=10)
nodes$color <- clrpal[nodes$group+1]
nedge <- nn
frvek <- 0:(nn-1)
tovek <- c(1:(nn-1),0)
edges <- data.frame(from = frvek, to = tovek)
net$groups <- data.frame(id=1:ng,colors<-clrpal[1:ng])
}
net$nodes <- nodes
net$edges <- edges
net$groups <- data.frame(id=1:ng,colors<-clrpal[1:ng])
})
output$visnetwork <- renderVisNetwork({
req(net$edges)
netout <- visNetwork(net$nodes,net$edges)
netout
})
output$networkD3 <- renderForceNetwork({
req(net$edges)
netout <- forceNetwork(
Links = net$edges, Nodes = net$nodes,
Source = "from", Target = "to",
NodeID = "label", Nodesize="size",
Group="group",opacity=1.0, zoom=T, fontSize = 12,
colourScale = JS(clrscale))
netout
})
output$networkstat <- renderText({
sprintf("\nNodes:%d Edges:%d Groups:%d",
nrow(net$nodes),nrow(net$edges),nrow(net$groups))
})
})
shinyApp(u,s)
看起来像这样:
总而言之,我会说它们都有优点和缺点,总的来说我认为 visNetwork
更容易使用,并且那些样条曲线看起来更酷,但是 networkD3
肯定快得多更大网络的初始化。 visNetwork
在 200 个节点的初始化过程中已经很痛苦了,尽管一旦绘制就很好了。
备注:
networkD3
鼠标缩放仅适用于真实浏览器(我使用的是 Chrome)。我无法让它在 R-Studio 浏览器中运行。快把我逼疯了。- 就此而言,Chrome 中的一切速度明显快于 R-Studio 浏览器。在真实的浏览器中进行基准测试和实际工作。