Speichern Sie die in einer glänzenden App erstellten Diagramme

Ich versuche herauszufinden, wie man DownloadButton verwendet, um ein Plot mit Glanz zu speichern. Das Beispiel im Paket zeigt DownloadButton / downloadHandler zum Speichern einer .csv. Ich werde daraus ein reproduzierbares Beispiel machen.

Für 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') ) )) 

Für 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()) } ) }) 

Wenn Sie diese Frage beantworten, sind Sie wahrscheinlich damit vertraut, aber um dies zum ui.R zu bringen, speichern Sie das obige in separaten Skripten ( ui.R und server.R in einem Ordner ( foo ) innerhalb des Arbeitsverzeichnisses) app, runApp("foo") .

Mit ggsave ich eine Fehlermeldung, dass gsave die filename nicht benutzen kann (denke ich). Wenn ich das Standard-Grafikgerät (wie unten) verwende, funktioniert das Download Plot ohne einen Fehler, aber es schreibt die Grafik nicht.

Irgendwelche Tipps, um downloadHandler zum Schreiben von Plots zu bekommen, wären willkommen.

Ich bin mir nicht sicher, ob diese Frage noch aktiv ist, aber sie ist die erste, die bei der Suche nach “Plots in einer glänzenden App” auftaucht. Daher wollte ich schnell hinzufügen, wie man ggsave mit downloadHandler in Übereinstimmung mit der ursprünglichen Frage arbeiten kann.

Die alternativen Strategien von juba mit direkter Ausgabe anstelle von gsave und alternative Strategie vorgeschlagen von alexwhan selbst beide funktionieren großartig, das ist nur für diejenigen, die unbedingt ggsave im DownloadHandler verwenden möchten).

Das von alexwhan gemeldete Problem wird dadurch verursacht, dass ggsave versucht, die Dateierweiterung dem richtigen Grafikgerät zuzuordnen. Die temporäre Datei hat jedoch keine Erweiterung, sodass die Zuordnung fehlschlägt. Dies kann behoben werden, indem das Gerät im ggsave functionsaufruf ggsave wie im Original-Codebeispiel (für ein png) gesetzt wird:

 output$downloadPlot < - downloadHandler( filename = function() { paste(input$dataset, '.png', sep='') }, content = function(file) { device <- function(..., width, height) grDevices::png(..., width = width, height = height, res = 300, units = "in") ggsave(file, plot = plotInput(), device = device) } ) 

Dieser Aufruf nimmt grundsätzlich die device für ein png , das ggsave intern zuweist (Sie können den ggsave functionscode betrachten, um die Syntax für jpg , pdf usw. zu sehen). Im Idealfall könnte man die Dateierweiterung (falls sie sich vom Dateinamen unterscheidet - wie hier für die temporäre Datei) als ggsave Parameter ggsave , aber diese Option ist derzeit in ggsave nicht verfügbar.


Ein minimales in sich geschlossenes Arbeitsbeispiel:

 library(shiny) library(ggplot2) runApp(list( ui = fluidPage(downloadButton('foo')), server = function(input, output) { plotInput = function() { qplot(speed, dist, data = cars) } output$foo = downloadHandler( filename = 'test.png', content = function(file) { device < - function(..., width, height) { grDevices::png(..., width = width, height = height, res = 300, units = "in") } ggsave(file, plot = plotInput(), device = device) }) } )) sessionInfo() # R version 3.1.1 (2014-07-10) # Platform: x86_64-pc-linux-gnu (64-bit) # # locale: # [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C # [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8 # [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 # [7] LC_PAPER=en_US.UTF-8 LC_NAME=C # [9] LC_ADDRESS=C LC_TELEPHONE=C # [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C # # attached base packages: # [1] stats graphics grDevices utils datasets methods base # # other attached packages: # [1] ggplot2_1.0.0 shiny_0.10.1 # # loaded via a namespace (and not attached): # [1] bitops_1.0-6 caTools_1.17 colorspace_1.2-4 digest_0.6.4 # [5] formatR_1.0 grid_3.1.1 gtable_0.1.2 htmltools_0.2.6 # [9] httpuv_1.3.0 labeling_0.2 MASS_7.3-34 munsell_0.4.2 # [13] plyr_1.8.1 proto_0.3-10 Rcpp_0.11.2 reshape2_1.4 # [17] RJSONIO_1.3-0 scales_0.2.4 stringr_0.6.2 tools_3.1.1 # [21] xtable_1.7-3 

Aktualisieren

Ab ggplot2 Version 2.0.0 unterstützt die ggsave function die Zeicheneingabe für den device , das heißt, die vom downloadHandler erstellte temporäre Datei kann jetzt mit einem direkten Aufruf von ggsave indem angegeben wird, dass die zu verwendende Erweiterung z. "pdf" (anstatt eine Gerätefunktion zu übergeben). Dies vereinfacht das obige Beispiel zu dem Folgenden

 output$downloadPlot < - downloadHandler( filename = function() { paste(input$dataset, '.png', sep='') }, content = function(file) { ggsave(file, plot = plotInput(), device = "png") } ) 

Hier ist eine Lösung, die gsave zum Speichern glänzender Plots ermöglicht. Es verwendet ein logisches Kontrollkästchen und eine Texteingabe, um ggsave() . Fügen Sie dies der ui.R Datei in sidebarPanel :

 textInput('filename', "Filename"), checkboxInput('savePlot', "Check to save") 

server.R das server.R Datei server.R statt der aktuellen output$plot reactivePlot hinzu:

 output$plot < - reactivePlot(function() { name <- paste0(input$filename, ".png") if(input$savePlot) { ggsave(name, plotInput(), type="cairo-png") } else print(plotInput()) }) 

Ein Benutzer kann dann den gewünschten Dateinamen in das Textfeld eingeben (ohne Erweiterung) und das Kontrollkästchen zum Speichern im App-Verzeichnis aktivieren. Wenn Sie das Kontrollkästchen deaktivieren, wird das Diagramm erneut gedruckt. Ich bin sicher, es gibt bessere Möglichkeiten, dies zu tun, aber zumindest kann ich jetzt gsave und cairo in Windows für viel schöner png Grafiken verwenden.

Bitte fügen Sie Ihre Vorschläge hinzu.

Ich habe es nicht geschafft mit ggsave , aber mit einem normalen Aufruf von png() scheint es in Ordnung zu sein.

Ich habe nur den output$downloadPlot Teil Ihrer server.R Datei server.R :

  output$downloadPlot < - downloadHandler( filename = function() { paste(input$dataset, '.png', sep='') }, content = function(file) { png(file) print(plotInput()) dev.off() }) 

Beachten Sie, dass ich einige Probleme mit der Version 0.3 von shiny hatte, aber es funktioniert mit dem neuesten von Github:

 library(devtools) install_github("shiny","rstudio") 

Das ist alt, aber immer noch der Top-Hit, wenn jemand “R shiny save ggplot” googelt, also werde ich einen weiteren Workaround einbringen. Ganz einfach … rufen Sie ggsave in derselben function auf, die Ihr Diagramm anzeigt, wodurch das Diagramm als Datei auf dem Server gespeichert wird.

 output$plot < - renderPlot({ ggsave("plot.pdf", plotInput()) plotInput() }) 

Verwenden Sie dann downloadHandler, und verwenden Sie file.copy() , um Daten aus der vorhandenen Datei in den Parameter "file" zu schreiben.

 output$dndPlot < - downloadHandler( filename = function() { "plot.pdf" }, content = function(file) { file.copy("plot.pdf", file, overwrite=TRUE) } ) 

functioniert bei mir.