programing tip

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

itbloger 2020. 10. 17. 10:04
반응형

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


나는 반짝 거리는 플롯을 저장하기 위해 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를 사용하는 모든 팁을 주시면 감사하겠습니다.


이 질문이 여전히 활성화되어 있는지 확실하지 않지만 "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    

최신 정보

As of ggplot2 version 2.0.0, the ggsave function supports character input for the device parameter, that means the temporary file created by the downloadHandler can now be saved with a direct call to ggsave by specifying that the extension to be used should be e.g. "pdf" (rather than passing in a device function). This simplifies the above example to the following

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

Here's a solution that allows using ggsave for saving shiny plots. It uses a logical checkbox and text input to call ggsave(). Add this to the ui.R file inside sidebarPanel:

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

Then add this to the server.R file instead of the current output$plot reactivePlot function:

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

A user can then type the desired filename in the textbox (without extension) and tick the checkbox to save in the app directory. Unchecking the box prints the plot again. I'm sure there are neater ways of doing this, but at least I can now use ggsave and cairo in windows for much nicer png graphics.

Please add any suggestions you may have.


I didn't manage to make it work with ggsave, but with a standard call to png() it seems to be okay.

I only changed the output$downloadPlot part of your server.R file :

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

Note that I had some problems with the 0.3 version of shiny, but it works with the latest from Github :

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

This is old, but still the top hit when someone googles "R shiny save ggplot", so I will contribute another workaround. Very simple... call ggsave in the same function that displays your graph, which will save the graph as a file on the server.

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

Then, use downloadHandler and use file.copy() to write data from the existing file to the "file" parameter.

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

Works for me.

참고URL : https://stackoverflow.com/questions/14810409/save-plots-made-in-a-shiny-app

반응형

'programing tip' 카테고리의 다른 글

Razor로 인코딩 된 HTML 표시  (0) 2020.10.18
"::" "."의 차이점은 무엇입니까?  (0) 2020.10.18
식의 차이  (0) 2020.10.17
하위 도메인에서 localStorage 사용  (0) 2020.10.17
System V IPC 대 POSIX IPC  (0) 2020.10.17