如何将 r ggplot 图存储为 html 代码片段
How to store r ggplot graph as html code snippet
我正在通过使用 ggplotly()
和 html 工具函数(如 h3()
和 html()
创建各种对象来创建 html 文档。然后我将它们作为列表提交给 htmltools::save_html()
以创建一个 html 文件。
我想直接将 ggplot 图表添加为图像,而不是附加所有情节花哨的东西。最后,我将创建一个自包含的 html 文件(无依赖项),情节内容会使该文件过大。
是否有一些函数可以将 ggplot 对象转换为某些 html 类型的对象?或者我是否必须将 ggplot 保存为 .png 文件,然后将 .png 文件读入我添加到 save_html() 函数列表中的某个对象?
我的 R 代码看起来像这样:
library("tidyverse")
library("plotly")
library("htmltools")
HTMLOut <- "c:/Users/MrMagoo/My.html")
df <- data.frame(x=1:25, y=c(1:25*1:25))
g7 <- ggplot(df,aes(x=x, y=y)) + geom_point()
p7 <- ggplotly(g7) # I would like to use something other than ggplotly here. Just capturing the ggplot as an image would be fine.
# create other objects to add to the html file
t7 <- h2(id="graph7", "Title for graph #7")
d7 <- p("description of graph 7")
save_html(list(t7, p7, d7), HTMLOut)
# of course, the real code has many more objects in that list – more graphs, text, tables, etc.
我想用不会导致 save_html 函数出错的方式将 plotly 对象 (p7) 替换为只显示 g7 的对象。
本来希望能找到一个可以直接Base64 encode ggplot 对象的函数,但看来我首先需要将'ggplot'对象输出为. png 文件(或 SVG,根据 Teng L,如下),然后对其进行 base64 编码。我希望有更直接的方法,但我最终可能会这样做,如 中那样,以
结尾
g7img <- "<img src=\"data:image/png;base64,(base64encode string)\""
g7img <- htmltools::html(g7img)
如果要将绘图保存为动态 plotly
图表,可以使用 htmlwidgets::saveWidget
。这将生成一个独立的 html 文件。
这是一个最小的例子:
library(tidyverse);
library(plotly);
library(htmlwidgets);
df <- data.frame(x = 1:25, y = c(1:25 * 1:25))
gg <- ggplot(df,aes(x = x, y = y)) + geom_point()
# Save ggplotly as widget in file test.html
saveWidget(ggplotly(gg), file = "test.html");
我想你想要的可能接近以下之一:
您似乎正在创建 HTML 报告,但尚未签出 RMarkdown。它带有 Base64 编码。当您创建 RMarkdown 报告时,pandoc
会自动将任何图表转换为文档中的 HTML 元素,因此该报告是独立的。
SVG 图。这不太可能是您想要的,但是 SVG 图是基于标记语言的并且可能很容易移植。使用 ggsave()
时指定 .svg
扩展名,您应该会得到一个 SVG 图像。请注意,SVG 是绘图的原样实现,因此如果您有数千种形状和线条,文件大小可能会很大。
我最终生成了一个临时图像文件,然后在我调用的函数中对其进行 base64 编码 encodeGraphic()
(从 借用代码):
library(ggplot2)
library(RCurl)
library(htmltools)
encodeGraphic <- function(g) {
png(tf1 <- tempfile(fileext = ".png")) # Get an unused filename in the session's temporary directory, and open that file for .png structured output.
print(g) # Output a graphic to the file
dev.off() # Close the file.
txt <- RCurl::base64Encode(readBin(tf1, "raw", file.info(tf1)[1, "size"]), "txt") # Convert the graphic image to a base 64 encoded string.
myImage <- htmltools::HTML(sprintf('<img src="data:image/png;base64,%s">', txt)) # Save the image as a markdown-friendly html object.
return(myImage)
}
HTMLOut <- "~/TEST.html" # Say where to save the html file.
g <- ggplot(mtcars, aes(x=gear,y=mpg,group=factor(am),color=factor(am))) + geom_line() # Create some ggplot graph object
hg <- encodeGraphic(g) # run the function that base64 encodes the graph
forHTML <- list(h1("My header"), p("Lead-in text about the graph"), hg)
save_html(forHTML, HTMLOut) # output it to the html file.
这是对 的扩展。在这个答案中,我展示了 how 以有组织的方式在同一个 html 文件中组合多个绘图:
library("plotly")
library("htmltools")
# a small helper function to avoid repetition
my_func <- function(..., title){
## Description:
## A function to add title to put multiple gg plotly objects under a html heading
##
## Arguments:
## ...: a list of gg objects
## title: a character vector to specify the heading text
# get the ... in list format
lst <- list(...)
# create the heading
tmp_title <- htmltools::h1(title)
# convert each ggplot to ggplotly and put them under the same div html tag
tmp_plot <- lapply(lst, ggplotly) |>
htmltools::div()
# return the final object as list
return(list(tmp_title, tmp_plot))
}
# a toy data
df <- data.frame(x = 1:25, y = c(1:25 * 1:25))
# the ggplot object using the toy data
gg <- ggplot(df,aes(x = x, y = y)) + geom_point()
# put everything in order
final_list <- list(my_func(obj = list(gg, gg, gg), title = "The first heading"),
my_func(obj = list(gg, gg), title = "The second heading"))
# write to disk as a unified HTML file
htmltools::save_html(html = final_list,
file = "index.html"))
免责声明:我特意这样做是为了避免使用 widgetframe R 包,并完全与 the documentation of plotly-r 相提并论。如果您愿意添加额外的依赖项和额外的抽象层,您可以阅读 link。当且仅当必要时,我更喜欢使用包。 :)
我正在通过使用 ggplotly()
和 html 工具函数(如 h3()
和 html()
创建各种对象来创建 html 文档。然后我将它们作为列表提交给 htmltools::save_html()
以创建一个 html 文件。
我想直接将 ggplot 图表添加为图像,而不是附加所有情节花哨的东西。最后,我将创建一个自包含的 html 文件(无依赖项),情节内容会使该文件过大。
是否有一些函数可以将 ggplot 对象转换为某些 html 类型的对象?或者我是否必须将 ggplot 保存为 .png 文件,然后将 .png 文件读入我添加到 save_html() 函数列表中的某个对象?
我的 R 代码看起来像这样:
library("tidyverse")
library("plotly")
library("htmltools")
HTMLOut <- "c:/Users/MrMagoo/My.html")
df <- data.frame(x=1:25, y=c(1:25*1:25))
g7 <- ggplot(df,aes(x=x, y=y)) + geom_point()
p7 <- ggplotly(g7) # I would like to use something other than ggplotly here. Just capturing the ggplot as an image would be fine.
# create other objects to add to the html file
t7 <- h2(id="graph7", "Title for graph #7")
d7 <- p("description of graph 7")
save_html(list(t7, p7, d7), HTMLOut)
# of course, the real code has many more objects in that list – more graphs, text, tables, etc.
我想用不会导致 save_html 函数出错的方式将 plotly 对象 (p7) 替换为只显示 g7 的对象。
本来希望能找到一个可以直接Base64 encode ggplot 对象的函数,但看来我首先需要将'ggplot'对象输出为. png 文件(或 SVG,根据 Teng L,如下),然后对其进行 base64 编码。我希望有更直接的方法,但我最终可能会这样做,如
g7img <- "<img src=\"data:image/png;base64,(base64encode string)\""
g7img <- htmltools::html(g7img)
如果要将绘图保存为动态 plotly
图表,可以使用 htmlwidgets::saveWidget
。这将生成一个独立的 html 文件。
这是一个最小的例子:
library(tidyverse);
library(plotly);
library(htmlwidgets);
df <- data.frame(x = 1:25, y = c(1:25 * 1:25))
gg <- ggplot(df,aes(x = x, y = y)) + geom_point()
# Save ggplotly as widget in file test.html
saveWidget(ggplotly(gg), file = "test.html");
我想你想要的可能接近以下之一:
您似乎正在创建 HTML 报告,但尚未签出 RMarkdown。它带有 Base64 编码。当您创建 RMarkdown 报告时,
pandoc
会自动将任何图表转换为文档中的 HTML 元素,因此该报告是独立的。SVG 图。这不太可能是您想要的,但是 SVG 图是基于标记语言的并且可能很容易移植。使用
ggsave()
时指定.svg
扩展名,您应该会得到一个 SVG 图像。请注意,SVG 是绘图的原样实现,因此如果您有数千种形状和线条,文件大小可能会很大。
我最终生成了一个临时图像文件,然后在我调用的函数中对其进行 base64 编码 encodeGraphic()
(从
library(ggplot2)
library(RCurl)
library(htmltools)
encodeGraphic <- function(g) {
png(tf1 <- tempfile(fileext = ".png")) # Get an unused filename in the session's temporary directory, and open that file for .png structured output.
print(g) # Output a graphic to the file
dev.off() # Close the file.
txt <- RCurl::base64Encode(readBin(tf1, "raw", file.info(tf1)[1, "size"]), "txt") # Convert the graphic image to a base 64 encoded string.
myImage <- htmltools::HTML(sprintf('<img src="data:image/png;base64,%s">', txt)) # Save the image as a markdown-friendly html object.
return(myImage)
}
HTMLOut <- "~/TEST.html" # Say where to save the html file.
g <- ggplot(mtcars, aes(x=gear,y=mpg,group=factor(am),color=factor(am))) + geom_line() # Create some ggplot graph object
hg <- encodeGraphic(g) # run the function that base64 encodes the graph
forHTML <- list(h1("My header"), p("Lead-in text about the graph"), hg)
save_html(forHTML, HTMLOut) # output it to the html file.
这是对
library("plotly")
library("htmltools")
# a small helper function to avoid repetition
my_func <- function(..., title){
## Description:
## A function to add title to put multiple gg plotly objects under a html heading
##
## Arguments:
## ...: a list of gg objects
## title: a character vector to specify the heading text
# get the ... in list format
lst <- list(...)
# create the heading
tmp_title <- htmltools::h1(title)
# convert each ggplot to ggplotly and put them under the same div html tag
tmp_plot <- lapply(lst, ggplotly) |>
htmltools::div()
# return the final object as list
return(list(tmp_title, tmp_plot))
}
# a toy data
df <- data.frame(x = 1:25, y = c(1:25 * 1:25))
# the ggplot object using the toy data
gg <- ggplot(df,aes(x = x, y = y)) + geom_point()
# put everything in order
final_list <- list(my_func(obj = list(gg, gg, gg), title = "The first heading"),
my_func(obj = list(gg, gg), title = "The second heading"))
# write to disk as a unified HTML file
htmltools::save_html(html = final_list,
file = "index.html"))
免责声明:我特意这样做是为了避免使用 widgetframe R 包,并完全与 the documentation of plotly-r 相提并论。如果您愿意添加额外的依赖项和额外的抽象层,您可以阅读 link。当且仅当必要时,我更喜欢使用包。 :)