如何在 R 中将 html 输出捕获为 png
How to capture html output as png in R
我使用 R 中 networkD3 包创建的交互式输出。我知道如何将输出保存为 html 页面,但我还需要将图表的 'static' 版本保存为 .png文件。
代码如下所示:
# 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)
我可以通过单击 'Export' 然后单击 'Save as Image' 来保存输出。但是,我更喜欢在我的代码中使用一些命令来保存图片。
我使用了此页面 https://github.com/hafen/trelliscope/blob/master/R/thumb.R 中的函数并尝试对其进行简化。
您需要从 http://phantomjs.org/download.html 安装 PhantomJS 并在环境变量中设置路径。
函数如下所示(参数 p
是 html 小部件,thumbName
是新 .png 文件的名称):
library(htmlwidgets)
widgetThumbnail <- function(p, thumbName, width = 1024, height = 768) {
phantom <- findPhantom()
success <- FALSE
if(phantom == "") {
message("** phantomjs dependency could not be found - thumbnail cannot be generated (run phantomInstall() for details)")
} else {
res <- try({
ff <- paste0(thumbName, ".html")
ffjs <- paste0(thumbName, ".js")
# don't want any padding
p$sizingPolicy$padding <- 0
suppressMessages(saveWidget(p, ff, selfcontained = FALSE))
js <- paste0("var page = require('webpage').create();
page.viewportSize = { width: ", width,", height: ", height," };
page.clipRect = { top: 0, left: 0, width: ", width,", height: ", height," };
page.open('", ff, "', function(status) {
console.log(\"Status: \" + status);
if(status === \"success\") {
page.render('", thumbName, ".png');
}
phantom.exit();
});")
cat(js, file = ffjs)
system2(phantom, ffjs)
})
if(!inherits(res, "try-error")) {
success <- TRUE
}
if(!file.exists(paste0(thumbName, ".png"))) {
success <- FALSE
}
}
if(!success) {
message("** could not create htmlwidget thumbnail... creating an empty thumbnail...")
}
}
#' Get instructions on how to install phantomjs
#' @export
phantomInstall <- function() {
message("Please visit this page to install phantomjs on your system: http://phantomjs.org/download.html")
}
# similar to webshot
findPhantom <- function() {
phantom <- Sys.which("phantomjs")
if(Sys.which("phantomjs") == "") {
if(identical(.Platform$OS.type, "windows")) {
phantom <- Sys.which(file.path(Sys.getenv("APPDATA"), "npm", "phantomjs.cmd"))
}
}
phantom
}
它创建 .js 文件,该文件获取您的 html 小部件,捕获屏幕并将 .js、.html 和 .png 文件保存到活动目录中:
# 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
plot = simpleNetwork(networkData)
# Save html as png
widgetThumbnail(p = plot, thumbName = "plot", height = 500)
只是对可能解决方案的更新。有一个名为 webshot
的包(由 W. Chang 等人开发)可以完成 html 页面的渲染和屏幕截图。
例如用法:
webshot::webshot("file.html")
要获取 html 文件,您可能需要查看 R. Vaidyanathan 等人的 htmlwidgets::saveWidget
一个完全可重现的示例(将 simpleNetwork.png
保存在您当前的工作目录中)
library(networkD3)
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)
sn <- simpleNetwork(networkData)
saveNetwork(sn, "sn.html")
library(webshot)
webshot("sn.html", "simpleNetwork.png")
我使用 R 中 networkD3 包创建的交互式输出。我知道如何将输出保存为 html 页面,但我还需要将图表的 'static' 版本保存为 .png文件。
代码如下所示:
# 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)
我可以通过单击 'Export' 然后单击 'Save as Image' 来保存输出。但是,我更喜欢在我的代码中使用一些命令来保存图片。
我使用了此页面 https://github.com/hafen/trelliscope/blob/master/R/thumb.R 中的函数并尝试对其进行简化。
您需要从 http://phantomjs.org/download.html 安装 PhantomJS 并在环境变量中设置路径。
函数如下所示(参数 p
是 html 小部件,thumbName
是新 .png 文件的名称):
library(htmlwidgets)
widgetThumbnail <- function(p, thumbName, width = 1024, height = 768) {
phantom <- findPhantom()
success <- FALSE
if(phantom == "") {
message("** phantomjs dependency could not be found - thumbnail cannot be generated (run phantomInstall() for details)")
} else {
res <- try({
ff <- paste0(thumbName, ".html")
ffjs <- paste0(thumbName, ".js")
# don't want any padding
p$sizingPolicy$padding <- 0
suppressMessages(saveWidget(p, ff, selfcontained = FALSE))
js <- paste0("var page = require('webpage').create();
page.viewportSize = { width: ", width,", height: ", height," };
page.clipRect = { top: 0, left: 0, width: ", width,", height: ", height," };
page.open('", ff, "', function(status) {
console.log(\"Status: \" + status);
if(status === \"success\") {
page.render('", thumbName, ".png');
}
phantom.exit();
});")
cat(js, file = ffjs)
system2(phantom, ffjs)
})
if(!inherits(res, "try-error")) {
success <- TRUE
}
if(!file.exists(paste0(thumbName, ".png"))) {
success <- FALSE
}
}
if(!success) {
message("** could not create htmlwidget thumbnail... creating an empty thumbnail...")
}
}
#' Get instructions on how to install phantomjs
#' @export
phantomInstall <- function() {
message("Please visit this page to install phantomjs on your system: http://phantomjs.org/download.html")
}
# similar to webshot
findPhantom <- function() {
phantom <- Sys.which("phantomjs")
if(Sys.which("phantomjs") == "") {
if(identical(.Platform$OS.type, "windows")) {
phantom <- Sys.which(file.path(Sys.getenv("APPDATA"), "npm", "phantomjs.cmd"))
}
}
phantom
}
它创建 .js 文件,该文件获取您的 html 小部件,捕获屏幕并将 .js、.html 和 .png 文件保存到活动目录中:
# 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
plot = simpleNetwork(networkData)
# Save html as png
widgetThumbnail(p = plot, thumbName = "plot", height = 500)
只是对可能解决方案的更新。有一个名为 webshot
的包(由 W. Chang 等人开发)可以完成 html 页面的渲染和屏幕截图。
例如用法:
webshot::webshot("file.html")
要获取 html 文件,您可能需要查看 R. Vaidyanathan 等人的 htmlwidgets::saveWidget
一个完全可重现的示例(将 simpleNetwork.png
保存在您当前的工作目录中)
library(networkD3)
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)
sn <- simpleNetwork(networkData)
saveNetwork(sn, "sn.html")
library(webshot)
webshot("sn.html", "simpleNetwork.png")