Use reactive expressions in renderPlot and downloa

2019-05-10 20:14发布

Use reactive expressions in renderPlot and download handler

I have had problems by using reactive expressions both in renderPlot() and in downloadHandler() in shiny applications. I want to do this to reduce maintenance and redundancy in my code.

The above issue works with "normal" plot functions like plot, hist, etc. In my application I'm using a more complex function which creates a plot. I have created a simplified version of it

helpfunc <- function(mean, sd) {
    hist(rnorm(1000, mean, sd))
    lines(1:10)
}

If you use this function now in your shiny app, it does not work when creating a reactive expression out of it. Neither by using plot() nor by using the reactive expression itself.

mwe <- function() {
app = list(
    ui = bootstrapPage(
         fluidPage(
            sidebarPanel(
                 sliderInput("mean", "choose mean", -10, 10, 1),
                 sliderInput("sd", "choose sd", 0, 5, 1)),
            mainPanel(
                plotOutput("hist"),
                downloadButton("histDownload")
            )
        )
        ),
server = function(input, output) {

    output$hist <- renderPlot(.hist())

    .hist <- reactive(helpfunc(input$mean, input$sd))

    output$histDownload <- downloadHandler(
        filename = function() {
            paste("hist.jpg")
        }, 
        content = function(file) {
            jpeg(file, quality = 100, width = 800, height = 800)
            .hist() ## works not for plot(.hist()) either
            dev.off()
        }
    )

}

标签: r render shiny
1条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-05-10 20:58

lines is basically a call to plot.xy. You have the same problem as you had before except this time you cannot assign the output of lines. As before you can assign the output of the hist function.

helpfunc <- function(mean, sd) {
  hist = hist(rnorm(1000, mean, sd))
  myLines = function(){lines(1:10)}
  myLines()
  list(hist = hist, lines = myLines)
}

mwe2 <- function() {


  app = list(
    ui = bootstrapPage(
      fluidPage(
        sidebarPanel(
          sliderInput("mean", "choose mean", -10, 10, 1),
          sliderInput("sd", "choose sd", 0, 5, 1)),
        mainPanel(
          plotOutput("hist"),
          downloadButton("histDownload")

        )
      )
    ),
    server = function(input, output) {

      output$hist <- renderPlot(.hist())

      .hist <- reactive(helpfunc(input$mean, input$sd))

      output$histDownload <- downloadHandler(
        filename = function() {
          paste("hist.jpg")
        }, 
        content = function(file) {
          myHist <- .hist()
          jpeg(file, quality = 100, width = 800, height = 800)
          plot(myHist$hist)
          myHist$lines()
          dev.off()
        }
      )

    }

  )
  runApp(app)
}
查看更多
登录 后发表回答