2013-02-11 18 views
58

私はダウンロードボタンを使って光沢のあるプロットを保存する方法を理解しようとしています。このパッケージの例では、.csvを保存するdownloadButton/downloadHandlerを示しています。私はそれに基づいて再現可能な例を作るつもりです。 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()) 
    } 
) 
}) 

については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') 
) 
)) 

については

あなたはこの質問に答えるしている場合、あなたはおそらくこれに精通しているが、この作業を取得するために、別々のスクリプトに上記を保存します( ui.Rおよびserver.Rを作業ディレクトリ内のフォルダ(foo)に追加します。光り輝くアプリケーションを実行するには、runApp("foo")を実行してください。

ggsaveを使用すると、ggsaveがfilename機能を使用できないことを示すエラーメッセージが表示されます(私は思う)。標準のグラフィックスデバイス(下記参照)を使用すると、Download Plotはエラーなく動作しますが、グラフィックは書き込まれません。

downloadHandlerがプロットを書くのに役立つヒントをいただければ幸いです。

答えて

35

この質問がまだ有効かどうかはわかりませんが、「光沢のあるアプリケーションでプロットを保存」を検索したときに最初に表示されたのは、元の行に沿ってggsaveをdownloadHandlerと連携させる方法をすばやく追加する質問。

ggsaveの代わりに直接出力を使用し、alexwhan自身が提案した代替戦略を使用して提案された代替戦略はどちらも素晴らしいです。これはdownloadHandlerでggsaveを絶対に使用したい人向けです)。

alexwhanによって報告された問題は、ggsaveがファイル拡張子を正しいグラフィックデバイスに一致させようとしているために発生します。ただし、テンポラリファイルには拡張子がないため、マッチングは失敗します。これは、(PNG用)元のコード例でのようなので、具体的ggsave関数呼び出しでデバイスを設定することによって改善することができる。

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) 
    } 
) 

このコールは、基本的に(ggsaveが内部割り当てることpngためdevice関数を取りjpgpdfなどの構文を確認するには、ggsaveファンクションコードを参照してください。おそらく、理想的には、ggsaveパラメータとしてファイル拡張子(ファイル名とは異なる場合 - テンポラリファイルの場合のように)を指定できますが、現在このオプションはggsaveでは利用できません。


は、最小限の自己完結型の作業例:

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  

更新ggplot2バージョン2.0.0のよう

は、ggsave機能が一時的に意味し、deviceパラメータの文字入力をサポートしていますdownloadHandlerで作成されたファイルは、ggsaveへの直接呼び出しで保存されるようになりました。 "pdf"(デバイス関数を渡すのではなく)。これは、これは古い以下

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

私はあなたの答えは実際にここで正しいと思います。デバイス(ラッパー)関数を作成する代わりに 'ggsave(file、plotInput()、device = png)'を使うこともできます。 –

+0

@sebkopf私は途中であなたの答えを忘れてしまいました。 – alexwhan

+1

@Yihuiこのソリューションは私にとってはうまくいかない:Rバージョン3.1.0、ggplot2_1.0.0 shiny_0.10.1。保存ボックスがポップアップし、保存をクリックしますが、ファイルは保存されません。誰でも確認できますか? – zx8754

17

私はそれをggsaveと動作させることはできませんでしたが、png()への標準呼び出しで問題はないようです。

私は、あなたのserver.Rファイルのoutput$downloadPlot一部変更されました:私は光沢の0.3バージョンでいくつかの問題を抱えていたが、それはGitHubのから最新のと連動し

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

注:

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

OK、ggsaveはdownloadHandlerを使用してこの手続きの段階では動作しないことに同意します。光沢のある0.3がdownloadHandlerで崩れ落ちる、そうだよ。私はggsaveを動作させるdownloadHandlerを避けることを考え出した別の解決策を投稿します。 – alexwhan

+1

@juba類似の(non-ggplot2)メソッドを使用して[pdfに出力しようとする](https://gist.github.com/geotheory/b0c36071b7c0c2b384db)が動作しない理由は何ですか?私はちょうど開いていない壊れたpdfを得る。 plotInputはプロットオブジェクトではなくプロットを出力できますか? – geotheory

20

ここでは、光沢のあるプロットを保存するためにggsaveを使用できるソリューションがあります。論理チェックボックスとテキスト入力を使用してggsave()を呼び出します。 sidebarPanel内部ui.Rファイルにこれを追加する:

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

そして代わりに現在output$plot reactivePlot関数のserver.Rファイルにこれを追加する:

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

次いで、ユーザは、(テキストボックスに所望のファイル名を入力することができ拡張子なし)、チェックボックスをチェックしてappディレクトリに保存します。チェックを外すとプロットが再印刷されます。私はこれをやるためのより良い方法があると確信していますが、少なくとも私はggsaveとカイロをもっと良いpngグラフィックスのためにウィンドウで使うことができます。

ご意見をお寄せください。

+0

'input $ filename'の周りに' isolate'ブロックを置かずに 'filename'テキストボックスを変更すると、ボックスがチェックされていればファイルの保存を促すでしょう。 – jpd527

13

に上記の例を簡略化し、誰かが「Rは、光沢のあるggplotを保存する」ので、私は別の回避策を貢献するグーグルまだトップヒット。非常に簡単です...あなたのグラフを表示する同じ関数でggsaveを呼び出すと、グラフがサーバ上のファイルとして保存されます。その後

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

、downloadHandlerを使用し、「ファイル」パラメータに既存のファイルからのデータを書き込むためにfile.copy()を使用しています。

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

Works for me。

関連する問題