Is it possible to programmatically export a list of networks one by one to PNG in the R package visNetwork?

Viewed 216

I tried sample codes for visExport() and is able to add a "Export as PNG" button to a Shiny webpage. But this would need user interaction to press the button to export the network to a PNG image file.

I have over hundred of networks and would like to export them each to a PNG file. And some of these would need regular updating. So it would be logistically nice to be able to export all them to PNG files without a user pressing the "Export as PNG" button for each of the network.

So is it possible to programmatically export a list of networks one by one to PNG? This would be just like for visSave() to export the HTML for each network one by one.

2 Answers

In reference to other post, here is working code making use of the webshot package.

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)
}

The short answer must be "Yes", but since you've not given us any sample code, it's impossible to give you a tested solution. But you say you have a hundred networks. Let's assume there in a vector networks. (A list would work as well with minor changes to the sample code below.) You can export one graph using a Shiny button. So you must have code to create a single network image. Suppose that's in a function createImageForNetwork(x), where x is a network. You'll also need a function to create an output file name for each image. Suppose that's called getFilename(x). Then something like the untested code below will do what you want:

exportNetworkImage <- function(x) {
  png(getFilename(x))
  createImageForNetwork(x)
  dev.off()
}
lapply(1:length(networks), function(x) exportNetworkImage(networks[x]))

If you want to do that with a single button click in your Shiny app, then just put that code inside the button's observeEvent handler.

Related