是否可以在 R 包 visNetwork 中以编程方式将网络列表逐一导出到 PNG?
Is it possible to programmatically export a list of networks one by one to PNG in the R package visNetwork?
我尝试了 visExport()
的示例代码,并且能够将 "Export as PNG" 按钮添加到 Shiny 网页。但这需要用户交互来按下按钮将网络导出到 PNG 图像文件。
我有超过一百个网络,我想将它们分别导出到一个 PNG 文件中。其中一些需要定期更新。因此,如果用户无需为每个网络按下 "Export as PNG" 按钮,就可以将它们全部导出为 PNG 文件,这在逻辑上会很好。
那么是否可以通过编程将网络列表逐一导出到 PNG?这就像 visSave()
为每个网络逐一导出 HTML。
简短的回答必须是 "Yes",但是由于您没有给我们任何示例代码,所以不可能给您一个经过测试的解决方案。但是你说你有一百个网络。让我们假设在一个向量 networks
中。 (只要对下面的示例代码稍作改动,列表就可以正常工作。)您可以使用闪亮按钮导出一个图表。所以你必须有代码来创建一个单一的网络图像。假设它在一个函数 createImageForNetwork(x)
中,其中 x
是一个网络。您还需要一个函数来为每个图像创建一个输出文件名。假设这叫做 getFilename(x)
。然后类似于下面未经测试的代码将执行您想要的操作:
exportNetworkImage <- function(x) {
png(getFilename(x))
createImageForNetwork(x)
dev.off()
}
lapply(1:length(networks), function(x) exportNetworkImage(networks[x]))
如果您想通过在 Shiny 应用程序中单击一个按钮来做到这一点,只需将该代码放入按钮的 observeEvent
处理程序中即可。
参考其他 ,这里是使用 webshot 包的工作代码。
library(visNetwork)
library(tidyverse)
library(webshot)
# create network data
nodes = data.frame(id = numeric(),label=character(),set = numeric(),stringsAsFactors = F)
edges = data.frame(from = numeric(),to = numeric(),set = numeric(),stringsAsFactors = F)
for (i in 1:10){
tempNodes <- data.frame(id = 1:15, label = paste("Label", 1:15), set = i)
tempEdges <- data.frame(from = trunc(runif(15)*(15-1))+1,
to = trunc(runif(15)*(15-1))+1, set = i)
nodes = rbind(nodes,tempNodes)
edges = rbind(edges,tempEdges)
}
# loop through each set to export to PNG
for (i in 1:max(nodes$set)){
subNodes = nodes[nodes$set==i,]
subEdges = edges[edges$set==i,]
network = visNetwork(subNodes, subEdges, width="100vw",height = "100vh") %>%
visLayout(randomSeed=1,improvedLayout=TRUE) %>%
visGroups(groupname = "actorImported",shape="circle") %>%
visEdges(smooth=FALSE) %>%
visPhysics(solver = "barnesHut")
fname = paste0("network",sprintf("%03d",i),".html")
visSave(network,fname)
webshot(fname,delay=0.5,zoom=2,file=paste0("network",sprintf("%03d",i),".png"),
vwidth=900,vheight=900)
}
我尝试了 visExport()
的示例代码,并且能够将 "Export as PNG" 按钮添加到 Shiny 网页。但这需要用户交互来按下按钮将网络导出到 PNG 图像文件。
我有超过一百个网络,我想将它们分别导出到一个 PNG 文件中。其中一些需要定期更新。因此,如果用户无需为每个网络按下 "Export as PNG" 按钮,就可以将它们全部导出为 PNG 文件,这在逻辑上会很好。
那么是否可以通过编程将网络列表逐一导出到 PNG?这就像 visSave()
为每个网络逐一导出 HTML。
简短的回答必须是 "Yes",但是由于您没有给我们任何示例代码,所以不可能给您一个经过测试的解决方案。但是你说你有一百个网络。让我们假设在一个向量 networks
中。 (只要对下面的示例代码稍作改动,列表就可以正常工作。)您可以使用闪亮按钮导出一个图表。所以你必须有代码来创建一个单一的网络图像。假设它在一个函数 createImageForNetwork(x)
中,其中 x
是一个网络。您还需要一个函数来为每个图像创建一个输出文件名。假设这叫做 getFilename(x)
。然后类似于下面未经测试的代码将执行您想要的操作:
exportNetworkImage <- function(x) {
png(getFilename(x))
createImageForNetwork(x)
dev.off()
}
lapply(1:length(networks), function(x) exportNetworkImage(networks[x]))
如果您想通过在 Shiny 应用程序中单击一个按钮来做到这一点,只需将该代码放入按钮的 observeEvent
处理程序中即可。
参考其他
library(visNetwork)
library(tidyverse)
library(webshot)
# create network data
nodes = data.frame(id = numeric(),label=character(),set = numeric(),stringsAsFactors = F)
edges = data.frame(from = numeric(),to = numeric(),set = numeric(),stringsAsFactors = F)
for (i in 1:10){
tempNodes <- data.frame(id = 1:15, label = paste("Label", 1:15), set = i)
tempEdges <- data.frame(from = trunc(runif(15)*(15-1))+1,
to = trunc(runif(15)*(15-1))+1, set = i)
nodes = rbind(nodes,tempNodes)
edges = rbind(edges,tempEdges)
}
# loop through each set to export to PNG
for (i in 1:max(nodes$set)){
subNodes = nodes[nodes$set==i,]
subEdges = edges[edges$set==i,]
network = visNetwork(subNodes, subEdges, width="100vw",height = "100vh") %>%
visLayout(randomSeed=1,improvedLayout=TRUE) %>%
visGroups(groupname = "actorImported",shape="circle") %>%
visEdges(smooth=FALSE) %>%
visPhysics(solver = "barnesHut")
fname = paste0("network",sprintf("%03d",i),".html")
visSave(network,fname)
webshot(fname,delay=0.5,zoom=2,file=paste0("network",sprintf("%03d",i),".png"),
vwidth=900,vheight=900)
}