DownloadButtonを使用して光沢のあるプロットを保存する方法を見つけようとしています。パッケージ内の例は、.csvを保存するdownloadButton/downloadHandlerを示しています。それに基づいて再現可能な例を作成します。
_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')
)
))
_
_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
_および_server.R
_にフォルダー(foo
)に保存します作業ディレクトリ内光沢のあるアプリを実行するには、runApp("foo")
を実行します。
ggsave
を使用すると、ggsaveがfilename
関数を使用できないことを示すエラーメッセージが表示されます(と思います)。標準のグラフィックデバイス(以下のような)を使用すると、_Download Plot
_はエラーなしで機能しますが、グラフィックは書き込まれません。
プロットを書くためにdownloadHandlerを動作させるためのヒントをいただければ幸いです。
この質問がまだアクティブであるかどうかはわかりませんが、「光沢のあるアプリでプロットを保存する」を検索したときに最初に出た質問なので、元の質問の行に沿ってggsaveをdownloadHandlerで動作させる方法をすばやく追加したかったのです。
Ggsaveの代わりに直接出力を使用してjubaが提案する代替戦略と、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)
}
)
この呼び出しは基本的に、device
が内部的に割り当てるpng
のggsave
関数を取ります(ggsave
関数コードを見て、jpg
の構文を確認できます。 pdf
など)。おそらく、理想的には、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")
}
)
以下は、光沢のあるプロットを保存するためにggsaveを使用できるソリューションです。論理チェックボックスとテキスト入力を使用して、ggsave()
を呼び出します。これをsidebarPanel
内のui.R
ファイルに追加します:
textInput('filename', "Filename"),
checkboxInput('savePlot', "Check to save")
次に、これを現在のserver.R
reactPlot関数の代わりにoutput$plot
ファイルに追加します。
output$plot <- reactivePlot(function() {
name <- paste0(input$filename, ".png")
if(input$savePlot) {
ggsave(name, plotInput(), type="cairo-png")
}
else print(plotInput())
})
ユーザーは、テキストボックスに目的のファイル名(拡張子なし)を入力し、チェックボックスをオンにしてアプリディレクトリに保存できます。ボックスをオフにすると、プロットが再び印刷されます。これを行うためのきちんとした方法があると確信していますが、少なくとも今では、はるかに優れたPNGグラフィックスのためにウィンドウでggsaveとcairoを使用できます。
提案があれば追加してください。
私はそれをggsave
で動作させることができませんでしたが、png()
への標準的な呼び出しでは問題ないようです。
output$downloadPlot
ファイルのserver.R
部分のみを変更しました:
output$downloadPlot <- downloadHandler(
filename = function() { paste(input$dataset, '.png', sep='') },
content = function(file) {
png(file)
print(plotInput())
dev.off()
})
Shinyの0.3バージョンにはいくつか問題がありましたが、Githubの最新版では動作することに注意してください。
library(devtools)
install_github("shiny","rstudio")
これは古いですが、誰かが「R shiny save ggplot」をグーグルで検索したときのトップヒットなので、別の回避策を提供します。非常に簡単です...グラフを表示するのと同じ関数でggsaveを呼び出すと、グラフがサーバーにファイルとして保存されます。
_output$plot <- renderPlot({
ggsave("plot.pdf", plotInput())
plotInput()
})
_
次に、downloadHandlerを使用し、file.copy()
を使用して、既存のファイルから「file」パラメーターにデータを書き込みます。
_output$dndPlot <- downloadHandler(
filename = function() {
"plot.pdf"
},
content = function(file) {
file.copy("plot.pdf", file, overwrite=TRUE)
}
)
_
私のために働く。