如何将r ggplot图形存储为html代码片段

11

我通过创建各种对象使用ggplotly()和htmltools函数,如h3()html()创建一个html文档。然后,我将它们作为列表提交给htmltools::save_html()来创建一个html文件。

我希望直接将ggplot图表添加为图片,而不是附加所有的plotly功能。最终,我将创建一个独立的html文件(没有依赖项),而plotly的东西会使该文件过大。

是否有一些函数可以将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.

我想用一些代替plotly对象(p7)的东西,以一种不会导致save_html功能出错的方式呈现g7。

我曾希望找到一个函数可以直接对ggplot对象进行Base64编码,但似乎我需要先将'ggplot'对象输出为.png文件(或SVG,根据Teng L的建议),然后再进行base64编码。虽然我希望有更直接的方法,但最终可能会采取这种方法,就像https://dev59.com/X1wX5IYBdhLWcg3wwx1S#33410766中所示,最后以...结尾。

g7img <- "<img src=\"data:image/png;base64,(base64encode string)\""
g7img <- htmltools::html(g7img)

你看过这个帖子吗? - mnm
谢谢,我看到那篇帖子了。我想避免使用plotly,因为它创建的自包含HTML文件很大(超过2兆字节),以支持其提供的所有交互功能。 - user3799203
4个回答

12
如果您想将图形保存为动态的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");

7

我最终生成了一个临时图像文件,然后在我称为encodeGraphic()的函数中对其进行base64编码(借用LukeA的帖子中的代码):

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.

有没有一种方法可以控制图片的宽度? - Urvah Shabbir
有没有办法使用“forHTML” HTML代码,仍然像真正的Plotly图表一样具有交互性?我想知道,因为我很难将一个Plotly图表作为HTML输出添加到WordPress帖子或页面中...但是使用HTML代码“forHTML”可以...尽管它不再具有交互性... - H. berg

0

我认为你想要的可能接近以下内容之一:

  1. 看起来你正在创建HTML报告,但还没有检查RMarkdown。它带有Base64编码。当您创建RMarkdown报告时,pandoc会自动将任何绘图转换为文档中的HTML元素,因此报告是自包含的。

  2. SVG绘图。这不太可能是你想要的,但SVG绘图是基于标记语言的,并且可以轻松移植。在使用ggsave()时指定.svg扩展名,应该会得到一个SVG图像。请注意,SVG是绘图的原样实现,因此如果您有数千个形状和线条,则文件大小可能很大。


SVG可能是一个不错的解决方案。我在原帖中添加了更多关于将ggplot保存到文件的内容。 - user3799203

0

这是 Maurits Evers post的扩展内容。在这个答案中,我将展示如何以有组织的方式将多个 plotly 图表合并到同一个 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包,并完全与 plotly-r的文档保持一致。如果您习惯于添加额外的依赖和抽象层,则可以阅读该链接。 我只在必要时使用软件包。 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接