빛나는 앱에서 만든 플롯 저장


85

나는 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").

를 사용하면 ggsaveggsave가 filename기능을 사용할 수 없다는 오류 메시지가 나타납니다 (내 생각에). 표준 그래픽 장치 (아래처럼) Download Plot를 사용하면 오류없이 작동하지만 그래픽을 쓰지 않습니다.

플롯 작성을 위해 downloadHandler를 사용하는 모든 팁을 주시면 감사하겠습니다.

답변:


69

이 질문이 여전히 활성화되어 있는지 확실하지 않지만 "Saving plots in shiny app"을 검색 할 때 처음으로 나온 질문이므로 ggsave가 원래 질문의 줄을 따라 downloadHandler와 함께 작동하도록하는 방법을 빠르게 추가하고 싶었습니다.

ggsave 대신 직접 출력을 사용하는 juba가 제안한 대체 전략과 alexwhan 자신이 제안한 대체 전략은 모두 훌륭하게 작동합니다. 이것은 downloadHandler에서 ggsave를 절대적으로 사용하려는 사람들을위한 것입니다.

alexwhan이보고 한 문제는 ggsave가 파일 확장자를 올바른 그래픽 장치와 일치 시키려고 시도했기 때문에 발생합니다. 그러나 임시 파일에는 확장자가 없으므로 일치가 실패합니다. 이것은 ggsave원래 코드 예제 (png의 경우)와 같이 함수 호출 에서 장치를 구체적으로 설정하여 해결할 수 있습니다 .

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

이 호출은 기본적으로 소요 deviceA의 기능을 pngggsave내부 양수인 (당신은 볼 수 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")
    }
)

1
나는 당신의 대답이 실제로 올바른 대답이라고 믿습니다. ggsave(file, plotInput(), device = png)장치 (래퍼) 기능을 만드는 대신 사용할 수도 있습니다.
Yihui Xie

@sebkopf 나는 중간에 당신의 대답을 놓쳤습니다!
alexwhan 2014-08-24

1
@Yihui이 솔루션은 나를 위해 작동하지 않습니다 : R 버전 3.1.0, ggplot2_1.0.0 shiny_0.10.1. 저장 상자가 나타나면 저장을 클릭하지만 파일이 저장되지 않습니다. 누구든지 확인할 수 있습니까?
zx8754 2014-08-28

3
@ zx8754 방금 전체 예제를 답변에 추가했습니다. RStudio 뷰어에는 파일을 다운로드 할 수 없다는 알려진 버그가 있으므로 RStudio에서 보는 대신 웹 브라우저에서 실행해야합니다.
Yihui Xie

1
@sebkopf 예, 실제 예제를 시도한 후에 깨달았으므로 여기에서 첫 번째 의견이 실제로 잘못되었습니다. 설명해 주셔서 감사합니다!
Yihui Xie 2014 년

24

다음은 반짝이는 플롯을 저장하기 위해 ggsave를 사용할 수있는 솔루션입니다. 논리적 확인란과 텍스트 입력을 사용하여 ggsave(). 다음을 ui.R내부 파일에 추가하십시오 sidebarPanel.

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

그런 다음 server.R현재 output$plotreactPlot 함수 대신 파일에 다음을 추가 합니다.

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

그런 다음 사용자는 텍스트 상자에 원하는 파일 이름 (확장자 없음)을 입력하고 확인란을 선택하여 앱 디렉토리에 저장할 수 있습니다. 상자를 선택 취소하면 플롯이 다시 인쇄됩니다. 이 작업을 수행하는 더 좋은 방법이 있다고 확신하지만 적어도 이제는 훨씬 더 멋진 png 그래픽을 위해 창에서 ggsave와 cairo를 사용할 수 있습니다.

제안 사항이 있으면 추가하십시오.


isolate주위 에 블록이 없으면 상자를 선택한 경우 텍스트 상자를 input$filename변경 filename하면 파일을 저장하라는 메시지가 표시됩니다.
jpd527 2014

23

나는 그것을에서 작동하도록 관리하지 못했지만 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()
    })

0.3 버전의 shiny에서 몇 가지 문제가 있었지만 Github의 최신 버전에서 작동합니다.

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

좋아, 나는 ggsave가 downloadHandler로 진행하는이 단계에서 작동하지 않을 것이라는 점을 받아 들일 것입니다. 반짝이는 0.3은 downloadHandler와 함께 떨어집니다. ggsave가 작동하도록하는 downloadHandler를 피하는 대안을 게시 할 것입니다.
alexwhan 2013

1
@juba 유사한 (비 -ggplot2) 방법 으로 pdf로 출력하려는 ​​시도가 작동하지 않는 이유는 무엇입니까? 열리지 않는 깨진 PDF가 나타납니다. plotInput이 플롯 객체 대신 플롯을 전달할 수 없습니까?
geotheory

20

이것은 오래되었지만 누군가 "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)
    }
)

나를 위해 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.