将反应图从闪亮的应用程序保存为 png 到临时目录

发布于 2025-01-20 11:56:18 字数 3294 浏览 3 评论 0原文

这个问题非常基本,与 如何将反应图保存为 png 到闪亮应用程序中的工作目录

我必须更改我的策略,从 Rmarkdown 中的闪亮应用程序创建绘图。

为此,我需要完成这个简单的任务:

如何将此图作为 png 保存到临时文件夹中?

背景:保存到临时文件夹后,我将其传输到 R markdown 以创建报告。

library(shiny)

ui <- basicPage(
  plotOutput("plot1"),
)

server <- function(input, output) {
  output$plot1 <- renderPlot({
    plot(mtcars$wt, mtcars$mpg)
  })
}
shinyApp(ui, server)

更新:我的原始代码如下所示。我无法提供一个可重现的示例,因为它太复杂了:

我怎样才能实现 ismirsehregal 对此代码的答案:

# plot: Radarplot ------

output$radar <- renderChartJSRadar({
  chartJSRadar(PSA_13()[,c(1,2,6)],
               main = "XXX",
               maxScale = 100, scaleStepWidth = 10, scaleStartValue = 0, labelSize = 12, 
               addDots = TRUE, showToolTipLabel = TRUE, showLegend = TRUE, lineAlpha = 0.8, 
               polyAlpha = 0.2, responsive = FALSE, 
               colMatrix = col2rgb(c("orange", "navy" ,"grey")))
})

# create markdown report with radar plot ----------------------------------

output$report <- downloadHandler(
  filename = "report.pdf",
    content = function(file) {
      td <- tempdir()
      tempReport <- file.path(td, "report.Rmd")
      tempLogo <- file.path(td, "logo.png")
      file.copy("report.Rmd", tempReport, overwrite = TRUE)
      file.copy("logo.png", tempLogo, overwrite = TRUE)
    
    params <- list(scores = PSA_13()[,c(1,2,6)])
                   
    
    rmarkdown::render(tempReport, output_file = file,
                      params = params,
                      envir = new.env(parent = globalenv())
    )
  }
)

report.Rmd

    ---
geometry: margin=20truemm
fontfamily: mathpazo
fontsize: 11pt
documentclass: article
classoption: a4paper
urlcolor: blue
output: 
    pdf_document
header-includes:
   - \usepackage{fancyhdr}
   - \pagestyle{fancy}
   - \rhead{\includegraphics[width = .05\textwidth]{logo.png}}
params: 
    scores: NA
    plot_object: NA
---
\pagenumbering{gobble}

```{r setup, include=FALSE}
knitr::opts_chunk$set()
library(draw)
```

```{r rectangle, echo=FALSE}
drawBox(x =1.3, y = 3.7, width = 2.5, height = 1)
```

\vspace{-80truemm}

```{r plotout, echo=FALSE, message=FALSE, out.width='100%'}
params$plot_object
```


<!-- ```{r, echo=FALSE, out.width="100%", } -->
<!-- chartJSRadar(params$scores, width = 700, height = 700, -->
<!--              main = "Peritoneal Surface Calculator Radarchart", -->
<!--              maxScale = 100, -->
<!--              scaleStepWidth = 10, -->
<!--              scaleStartValue = 0, -->
<!--              labelSize = 14, -->
<!--              addDots = TRUE, -->
<!--              showToolTipLabel = FALSE, -->
<!--              showLegend = TRUE, -->
<!--              lineAlpha = 0.8, -->
<!--              polyAlpha = 0.2, -->
<!--              responsive = FALSE, -->
<!--              colMatrix = col2rgb(c("orange", "navy" ,"grey"))) -->
<!-- ``` -->

我觉得非常接近解决方案,非常感谢您抽出时间!

This question is quite basic and related to some questions before How to save reactive plot as png to working directory in a shiny app

I had to change my strategy creating a plot from a shiny app in Rmarkdown.

For this I need to accomplish this simple task:

How can I save this plot to the temp folder as png?

Background: After saving to temp folder I will transfer it to R markdown to create a report.

library(shiny)

ui <- basicPage(
  plotOutput("plot1"),
)

server <- function(input, output) {
  output$plot1 <- renderPlot({
    plot(mtcars$wt, mtcars$mpg)
  })
}
shinyApp(ui, server)

Update: My original code looks like this. I can't provide a reproducible example with this because it is to complex:

How can I implement the answer by ismirsehregal to this code:

# plot: Radarplot ------

output$radar <- renderChartJSRadar({
  chartJSRadar(PSA_13()[,c(1,2,6)],
               main = "XXX",
               maxScale = 100, scaleStepWidth = 10, scaleStartValue = 0, labelSize = 12, 
               addDots = TRUE, showToolTipLabel = TRUE, showLegend = TRUE, lineAlpha = 0.8, 
               polyAlpha = 0.2, responsive = FALSE, 
               colMatrix = col2rgb(c("orange", "navy" ,"grey")))
})

# create markdown report with radar plot ----------------------------------

output$report <- downloadHandler(
  filename = "report.pdf",
    content = function(file) {
      td <- tempdir()
      tempReport <- file.path(td, "report.Rmd")
      tempLogo <- file.path(td, "logo.png")
      file.copy("report.Rmd", tempReport, overwrite = TRUE)
      file.copy("logo.png", tempLogo, overwrite = TRUE)
    
    params <- list(scores = PSA_13()[,c(1,2,6)])
                   
    
    rmarkdown::render(tempReport, output_file = file,
                      params = params,
                      envir = new.env(parent = globalenv())
    )
  }
)

report.Rmd

    ---
geometry: margin=20truemm
fontfamily: mathpazo
fontsize: 11pt
documentclass: article
classoption: a4paper
urlcolor: blue
output: 
    pdf_document
header-includes:
   - \usepackage{fancyhdr}
   - \pagestyle{fancy}
   - \rhead{\includegraphics[width = .05\textwidth]{logo.png}}
params: 
    scores: NA
    plot_object: NA
---
\pagenumbering{gobble}

```{r setup, include=FALSE}
knitr::opts_chunk$set()
library(draw)
```

```{r rectangle, echo=FALSE}
drawBox(x =1.3, y = 3.7, width = 2.5, height = 1)
```

\vspace{-80truemm}

```{r plotout, echo=FALSE, message=FALSE, out.width='100%'}
params$plot_object
```


<!-- ```{r, echo=FALSE, out.width="100%", } -->
<!-- chartJSRadar(params$scores, width = 700, height = 700, -->
<!--              main = "Peritoneal Surface Calculator Radarchart", -->
<!--              maxScale = 100, -->
<!--              scaleStepWidth = 10, -->
<!--              scaleStartValue = 0, -->
<!--              labelSize = 14, -->
<!--              addDots = TRUE, -->
<!--              showToolTipLabel = FALSE, -->
<!--              showLegend = TRUE, -->
<!--              lineAlpha = 0.8, -->
<!--              polyAlpha = 0.2, -->
<!--              responsive = FALSE, -->
<!--              colMatrix = col2rgb(c("orange", "navy" ,"grey"))) -->
<!-- ``` -->

I feel quite near to the solution and I am very grateful for your time!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

青衫负雪 2025-01-27 11:56:18

无需保存临时 png 文件。我们可以使用 recordPlot 代替:

library(shiny)
library(datasets)

writeLines(con = "report.Rmd", text = "---
title: 'Plot report'
output: html_document
params:
  plot_object: NA
---

```{r plotout, echo=FALSE, message=FALSE, out.width='100%'}
params$plot_object
```")

ui = fluidPage(
  plotOutput("plot1"),
  downloadButton("report_button", "Generate report")
)

server = function(input, output, session) {
  reactivePlot1 <- reactive({
    plot(mtcars$wt, mtcars$mpg)
    recordPlot()
  })
  
  output$plot1 <- renderPlot({
    reactivePlot1()
  })
  
  output$report_button <- downloadHandler(
    filename = "report.html",
    content = function(file) {
      tempReport <- tempfile(fileext = ".Rmd") # make sure to avoid conflicts with other shiny sessions if more params are used
      file.copy("report.Rmd", tempReport, overwrite = TRUE)
      rmarkdown::render(tempReport, output_format = "html_document", output_file = file, output_options = list(self_contained = TRUE),
                        params = list(plot_object = reactivePlot1())
      )
    }
  )
}

shinyApp(ui, server)

请参阅我的此处的相关答案


OP 更新后 - 使用虚拟数据:

app.R

library(shiny)
library(radarchart)

scores <- data.frame("Label"=c("Communicator", "Data Wangler", "Programmer",
                               "Technologist",  "Modeller", "Visualizer"),
                     "Rich" = c(9, 7, 4, 5, 3, 7),
                     "Andy" = c(7, 6, 6, 2, 6, 9),
                     "Aimee" = c(6, 5, 8, 4, 7, 6))

ui = fluidPage(
  chartJSRadarOutput("radar", width = "450", height = "300"),
  downloadButton("report", "Generate report")
)

server = function(input, output, session) {
  reactiveRadar <- reactive({
    chartJSRadar(scores, maxScale = 10, showToolTipLabel=TRUE)
  })
  
  # plot: Radarplot ------
  output$radar <- renderChartJSRadar({
    reactiveRadar()
  })
  
  # create markdown report with radar plot ----------------------------------
  
  output$report <- downloadHandler(
    filename = "report.html",
    content = function(file) {
      td <- tempdir()
      tempReport <- file.path(td, "report.Rmd")
      # tempLogo <- file.path(td, "logo.png")
      file.copy("report.Rmd", tempReport, overwrite = TRUE)
      # file.copy("logo.png", tempLogo, overwrite = TRUE)
      
      params <- list(scores = "Test", plot_object = reactiveRadar()) # scores = PSA_13()[,c(1,2,6)]
      
      rmarkdown::render(tempReport, output_file = file,
                        params = params,
                        envir = new.env(parent = globalenv())
      )
    }
  )
}

shinyApp(ui, server)

report.Rmd

---
geometry: margin=20truemm
fontfamily: mathpazo
fontsize: 11pt
documentclass: article
classoption: a4paper
urlcolor: blue
output: 
    html_document
header-includes:
   - \usepackage{fancyhdr}
   - \pagestyle{fancy}
   # - \rhead{\includegraphics[width = .05\textwidth]{logo.png}}
params: 
    scores: NA
    plot_object: NA
---
\pagenumbering{gobble}

```{r setup, include=FALSE}
knitr::opts_chunk$set()
library(draw)
```

```{r rectangle, echo=FALSE}
drawBox(x =1.3, y = 3.7, width = 2.5, height = 1)
```

\vspace{-80truemm}

```{r plotout, echo=FALSE, message=FALSE, out.width='100%'}
params$plot_object
```

There is no need to save a temporary png file. We can use recordPlot instead:

library(shiny)
library(datasets)

writeLines(con = "report.Rmd", text = "---
title: 'Plot report'
output: html_document
params:
  plot_object: NA
---

```{r plotout, echo=FALSE, message=FALSE, out.width='100%'}
params$plot_object
```")

ui = fluidPage(
  plotOutput("plot1"),
  downloadButton("report_button", "Generate report")
)

server = function(input, output, session) {
  reactivePlot1 <- reactive({
    plot(mtcars$wt, mtcars$mpg)
    recordPlot()
  })
  
  output$plot1 <- renderPlot({
    reactivePlot1()
  })
  
  output$report_button <- downloadHandler(
    filename = "report.html",
    content = function(file) {
      tempReport <- tempfile(fileext = ".Rmd") # make sure to avoid conflicts with other shiny sessions if more params are used
      file.copy("report.Rmd", tempReport, overwrite = TRUE)
      rmarkdown::render(tempReport, output_format = "html_document", output_file = file, output_options = list(self_contained = TRUE),
                        params = list(plot_object = reactivePlot1())
      )
    }
  )
}

shinyApp(ui, server)

Please see my related answer here.


After OPs update - using dummy data:

app.R:

library(shiny)
library(radarchart)

scores <- data.frame("Label"=c("Communicator", "Data Wangler", "Programmer",
                               "Technologist",  "Modeller", "Visualizer"),
                     "Rich" = c(9, 7, 4, 5, 3, 7),
                     "Andy" = c(7, 6, 6, 2, 6, 9),
                     "Aimee" = c(6, 5, 8, 4, 7, 6))

ui = fluidPage(
  chartJSRadarOutput("radar", width = "450", height = "300"),
  downloadButton("report", "Generate report")
)

server = function(input, output, session) {
  reactiveRadar <- reactive({
    chartJSRadar(scores, maxScale = 10, showToolTipLabel=TRUE)
  })
  
  # plot: Radarplot ------
  output$radar <- renderChartJSRadar({
    reactiveRadar()
  })
  
  # create markdown report with radar plot ----------------------------------
  
  output$report <- downloadHandler(
    filename = "report.html",
    content = function(file) {
      td <- tempdir()
      tempReport <- file.path(td, "report.Rmd")
      # tempLogo <- file.path(td, "logo.png")
      file.copy("report.Rmd", tempReport, overwrite = TRUE)
      # file.copy("logo.png", tempLogo, overwrite = TRUE)
      
      params <- list(scores = "Test", plot_object = reactiveRadar()) # scores = PSA_13()[,c(1,2,6)]
      
      rmarkdown::render(tempReport, output_file = file,
                        params = params,
                        envir = new.env(parent = globalenv())
      )
    }
  )
}

shinyApp(ui, server)

report.Rmd:

---
geometry: margin=20truemm
fontfamily: mathpazo
fontsize: 11pt
documentclass: article
classoption: a4paper
urlcolor: blue
output: 
    html_document
header-includes:
   - \usepackage{fancyhdr}
   - \pagestyle{fancy}
   # - \rhead{\includegraphics[width = .05\textwidth]{logo.png}}
params: 
    scores: NA
    plot_object: NA
---
\pagenumbering{gobble}

```{r setup, include=FALSE}
knitr::opts_chunk$set()
library(draw)
```

```{r rectangle, echo=FALSE}
drawBox(x =1.3, y = 3.7, width = 2.5, height = 1)
```

\vspace{-80truemm}

```{r plotout, echo=FALSE, message=FALSE, out.width='100%'}
params$plot_object
```
假扮的天使 2025-01-27 11:56:18

此处有多个选项。
在您的情况下,您可以使用这样的简单选项:

library(shiny)

ui <- basicPage(
  plotOutput("plot1"),
  actionButton("save", "Click to save")
)

server <- function(input, output) {
  output$plot1 <- renderPlot({
    plot(mtcars$wt, mtcars$mpg)
  })
  
  
  observeEvent("save", {
    png('C:/path/to/your_plot/plot_saved.png')
    plot(mtcars$wt, mtcars$mpg)
    dev.off()
  })
  
  
}
shinyApp(ui, server)

如果您想指定大小、分辨率等,您必须在observeEvent中自定义代码

There are multiple options here.
In your case you could go with a simple option like this:

library(shiny)

ui <- basicPage(
  plotOutput("plot1"),
  actionButton("save", "Click to save")
)

server <- function(input, output) {
  output$plot1 <- renderPlot({
    plot(mtcars$wt, mtcars$mpg)
  })
  
  
  observeEvent("save", {
    png('C:/path/to/your_plot/plot_saved.png')
    plot(mtcars$wt, mtcars$mpg)
    dev.off()
  })
  
  
}
shinyApp(ui, server)

If you want to specify size, resolution, etc. you will have to customize the code within the observeEvent

菩提树下叶撕阳。 2025-01-27 11:56:18

shinyscreenshot 库似乎是一个不错的选择。
与 fschier 答案类似,但这也适用于交互式绘图元素。

library(shiny)
library(shinyscreenshot) 

ui <- basicPage(
  actionButton("screenshot2", "Capture plot"),
  plotOutput("plot1")
  
)

server <- function(input, output) {
  output$plot1 <- renderPlot({
    plot(mtcars$wt, mtcars$mpg)
  })
  observeEvent(input$screenshot2, {
    screenshot(id = "plot1",
               filename = "image1",
               server_dir = ".")
  })
}
shinyApp(ui, server)

server_dir 参数定义图像的保存位置。
在此示例中,文件 image1.png 将保存在您的本地目录中。 “.png”会自动添加到文件名参数中。
一旦写出文件,就可以像任何图像一样读入您的 rmd 文档。

The shinyscreenshot library seems like a good option.
similar to fschier answer, but this will work with interactive plot elements as well.

library(shiny)
library(shinyscreenshot) 

ui <- basicPage(
  actionButton("screenshot2", "Capture plot"),
  plotOutput("plot1")
  
)

server <- function(input, output) {
  output$plot1 <- renderPlot({
    plot(mtcars$wt, mtcars$mpg)
  })
  observeEvent(input$screenshot2, {
    screenshot(id = "plot1",
               filename = "image1",
               server_dir = ".")
  })
}
shinyApp(ui, server)

The server_dir parameter defines where the image is saved.
In this example the file image1.png will be save in your local directory. ".png" is automatically added to the filename parameter.
Once written out file can be read into your rmd document as any image would.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文