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