Estoy tratando de averiguar cómo usar downloadButton para guardar un gráfico con shiny. El ejemplo del paquete demuestra downloadButton / downloadHandler para guardar un .csv. Voy a hacer un ejemplo reproducible basado en eso.
por ui.R
shinyUI(pageWithSidebar(
headerPanel('Downloading Data'),
sidebarPanel(
selectInput("dataset", "Choose a dataset:",
choices = c("rock", "pressure", "cars")),
downloadButton('downloadData', 'Download Data'),
downloadButton('downloadPlot', 'Download Plot')
),
mainPanel(
plotOutput('plot')
)
))
por server.R
library(ggplot2)
shinyServer(function(input, output) {
datasetInput <- reactive({
switch(input$dataset,
"rock" = rock,
"pressure" = pressure,
"cars" = cars)
})
plotInput <- reactive({
df <- datasetInput()
p <-ggplot(df, aes_string(x=names(df)[1], y=names(df)[2])) +
geom_point()
})
output$plot <- renderPlot({
print(plotInput())
})
output$downloadData <- downloadHandler(
filename = function() { paste(input$dataset, '.csv', sep='') },
content = function(file) {
write.csv(datatasetInput(), file)
}
)
output$downloadPlot <- downloadHandler(
filename = function() { paste(input$dataset, '.png', sep='') },
content = function(file) {
ggsave(file,plotInput())
}
)
})
Si está respondiendo a esta pregunta, probablemente esté familiarizado con esto, pero para que esto funcione, guarde lo anterior en scripts separados ( ui.R
y server.R
en una carpeta ( foo
) dentro del directorio de trabajo. Para ejecutar la aplicación brillante, ejecute runApp("foo")
.
Al usar ggsave
, aparece un mensaje de error que indica que ggsave no puede usar la filename
función (creo). Si utilizo el dispositivo gráfico estándar (como a continuación), Download Plot
funciona sin error, pero no escribe el gráfico.
Se agradecería cualquier consejo para que downloadHandler funcione para escribir gráficos.
ggsave(file, plotInput(), device = png)
lugar de crear una función de dispositivo (envoltorio).Aquí hay una solución que permite usar ggsave para guardar gráficos brillantes. Utiliza una casilla de verificación lógica y una entrada de texto para llamar
ggsave()
. Agregue esto alui.R
archivo dentrosidebarPanel
:textInput('filename', "Filename"), checkboxInput('savePlot', "Check to save")
Luego agregue esto al
server.R
archivo en lugar de laoutput$plot
función reactivePlot actual :output$plot <- reactivePlot(function() { name <- paste0(input$filename, ".png") if(input$savePlot) { ggsave(name, plotInput(), type="cairo-png") } else print(plotInput()) })
Luego, un usuario puede escribir el nombre de archivo deseado en el cuadro de texto (sin extensión) y marcar la casilla de verificación para guardar en el directorio de la aplicación. Al desmarcar la casilla, se imprime el gráfico nuevamente. Estoy seguro de que hay formas más ordenadas de hacer esto, pero al menos ahora puedo usar ggsave y cairo en Windows para obtener gráficos png mucho más agradables.
Agregue cualquier sugerencia que pueda tener.
fuente
isolate
bloque alrededor delinput$filename
, cualquier cambio en elfilename
cuadro de texto también solicitará que se guarde el archivo si el cuadro está marcado.No logré que funcione
ggsave
, pero con una llamada estándarpng()
parece estar bien.Solo cambié la
output$downloadPlot
parte de tuserver.R
archivo:output$downloadPlot <- downloadHandler( filename = function() { paste(input$dataset, '.png', sep='') }, content = function(file) { png(file) print(plotInput()) dev.off() })
Tenga en cuenta que tuve algunos problemas con la versión 0.3 de shiny, pero funciona con la última de Github:
library(devtools) install_github("shiny","rstudio")
fuente
Esto es antiguo, pero sigue siendo el principal éxito cuando alguien busca en Google "R shiny save ggplot", así que contribuiré con otra solución. Muy simple ... llame a ggsave en la misma función que muestra su gráfico, que guardará el gráfico como un archivo en el servidor.
output$plot <- renderPlot({ ggsave("plot.pdf", plotInput()) plotInput() })
Luego, use downloadHandler y use
file.copy()
para escribir datos desde el archivo existente en el parámetro "file".output$dndPlot <- downloadHandler( filename = function() { "plot.pdf" }, content = function(file) { file.copy("plot.pdf", file, overwrite=TRUE) } )
Funciona para mi.
fuente