gpt4 book ai didi

r - 为什么 ggplotly 在 rmarkdown 中不能像 ggplot 一样工作

转载 作者:行者123 更新时间:2023-12-01 04:25:02 33 4
gpt4 key购买 nike

我想使用 ggplotly因为它的副作用相同ggplot甚至graphics做。我的意思是当我 knitr::knitrmarkdown::render我期望的 Rmd 文档 print(obj)在哪里 objggplotly对象在报告中,但事实并非如此。

  • 谁能解释发生了什么?
  • 谁能告诉我如何实现我想做的事情。我希望能够在不返回对象的情况下将 ggplotly 图绘制到函数中(我想返回图的基础数据),并且我希望代码同时适用于 ggplot 和 ggplotly(即使用相同的代码ggplot 或 ggplotly)

  • 问题.R 文件
    #+ libs, echo = FALSE                                                                                                                                                                                                                                        
    suppressMessages({
    library(ggplot2)
    library(plotly)
    library(rmarkdown)
    })

    #+ functions decl, echo = FALSE
    df <- data.frame(x = 1:5, y = 1:5)
    f_0 <- function(df) {
    p <- ggplot(df, aes(x, y)) + geom_line()
    # p or plot(p) or print(p) works
    print(p)
    return(df)
    }
    f_1 <- function(df) {
    p <- ggplot(df, aes(x, y)) + geom_line()
    p <- ggplotly(p)
    # plot(p) crashes
    # print p does not print in report
    print(p)
    # p standalone does not work either
    p
    return(df)
    }

    #' # plots
    #' plot 0
    #+ plot_0
    res_0 <- f_0(df)
    #' plot 1
    #+ plot_1
    res_1 <- f_1(df)

    渲染此文件
    rmarkdown::render("question.R")

    输出

    output

    最佳答案

    编辑评论:作为一种风格,将计算和绘图分离为不同的函数通常是一个好主意,因为它增加了模块化,使代码更易于维护,并允许在没有参数蠕变的情况下进行更精细的控制。然后可以轻松地将各个函数的输出映射到单独的 knitr block 。

    最佳解决方案:我知道您特别询问不返回绘图对象,但我只想指出,将它与结果一起返回提供了最干净、最优雅的解决方案:

    ---
    output: html_document
    ---

    ```{r include=FALSE}
    library( tidyverse )
    df <- data_frame( x=1:5, y=1:5 )
    ```

    ```{r}
    f <- function(df) {
    gg <- ggplot(df, aes(x,y)) + geom_point()
    list( result=df, plot=plotly::ggplotly(gg) )
    }
    res <- f(df)
    res$plot
    ```

    但是,如果您绝对不能从函数返回一个 plotly 对象,您有一些选择。

    选项 1:将 plotly 对象存储到父框架,提供从 knitr block 对其的访问。
    ```{r}
    f1 <- function(df) {
    gg <- ggplot(df, aes(x,y)) + geom_point()
    assign("ggp", plotly::ggplotly(gg), envir=parent.frame())
    df # NOT returning a plot
    }
    res1 <- f1(df)
    ggp # Let knitr handle the rendering naturally
    ```

    选项 2:将绘图渲染为临时 .html,然后将其作为 iframe 导入
    ```{r, results='asis'}     # <-- note the "asis" chunk option
    f2 <- function(df)
    {
    gg <- ggplot(df, aes(x,y)) + geom_point()
    htmlwidgets::saveWidget( plotly::ggplotly(gg), "temp.html")
    print( htmltools::tags$iframe(src="temp.html", width=640, height=480) )
    df # NOT returning a plot
    }
    res2 <- f2(df)
    ```

    解释: Yihui 有错误可以指正,但是knitr 基本上是在幕后做“选项2”的。它将诸如 plotly 对象之类的 htmlwidgets 渲染到临时 .html 文件中,然后将这些临时文件组合起来以生成最终文档。它在函数内失败的原因是当执行离开函数范围时临时文件被删除。 (您可以使用 tempfile() 而不是永久的 "temp.html" 自己复制它; iframe 对象将在最终文档中显示“找不到文件”错误。)可能有一种方法可以修改 knitr 钩子(Hook)以保留临时文件,但这超出了我的知识范围。最后,基本的 ggplot 没有这个问题的原因对象是因为它们的输出进入绘图设备,该设备在调用帧中持续存在。

    关于r - 为什么 ggplotly 在 rmarkdown 中不能像 ggplot 一样工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59144842/

    33 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com