Home > database >  Save reactive plot to temp directory as png from shiny app
Save reactive plot to temp directory as png from shiny app

Time:04-11

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!

CodePudding user response:

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

CodePudding user response:

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
```
  • Related