在闪亮的应用程序中缓存基本ggplot并允许动态修改图层(leafletProxy等效于ggplot)

时间:2016-09-21 10:05:28

标签: r ggplot2 shiny

如果显示的基础数据集很大(下面的示例工作代码),在闪亮的应用程序中向ggplot添加/删除图层可能需要一段时间。

问题是:

有没有办法缓存 ggplot(基本情节)并添加/删除/修改额外(动态)图层而无需在闪亮的应用中重做整个情节? 也就是说,一个相当于 leafletProxy()的函数用于传单映射(参见leaflet Rstudio webpage中的工作示例)。

这个stackoverflow thread(下例中的选项B)提出了一种可能的解决方法,但是,它并没有阻止ggplot重做整个图。

工作代码示例:

library(shiny)
library(ggplot2)

shinyApp(
  shinyUI(
    fluidPage(
      sidebarLayout(
        sidebarPanel(
          checkboxInput("line", "Add line")
        ),
        mainPanel(
          plotOutput("plot")
        )
      )
    )
  ),
  shinyServer(function(input, output, session) {
    data(diamonds)
    vals <- reactiveValues(pdata=ggplot())

    observeEvent(input$line, {
      p <- ggplot(diamonds, aes(x=carat, y=depth)) + geom_point()
      if (input$line){
        lineData <- data.frame(x=c(1, 4), y = c(60, 75))
        p <- p + geom_line(data = lineData, aes(x=x, y=y), color = "red")
      }
      vals$pdata <- p
    })
    # Option A ------
    # output$plot <- renderPlot({
    #     vals$pdata
    # })
    #
    # Option B ------
    observeEvent(vals$pdata,{
      output$plot <- renderPlot({
        isolate(vals$pdata)
      })
    })

  })
)

1 个答案:

答案 0 :(得分:0)

您总是可以只绘制两个图,然后使用条件选择要显示的图。初始渲染速度很慢,但是初始化后效果很好。

library(shiny)
library(ggplot2)

shinyApp(
  shinyUI(
    fluidPage(
      sidebarLayout(
        sidebarPanel(
          checkboxInput("line", "Add line", value = TRUE)
          ),
        mainPanel(
          conditionalPanel(condition = 'input.line == false',
                           plotOutput("plot1"),
                           ),
          conditionalPanel(condition = 'input.line == true',
                           plotOutput("plot2"),
                           ),
          )
        )
      )
    ),
  shinyServer(function(input, output, session) {
    #data(diamonds)


    # Option C -------
    output$plot1 <- renderPlot({
      ggplot(diamonds, aes(x=carat, y=depth)) + geom_point()
    })
    output$plot2 <- renderPlot({
      lineData <- data.frame(x=c(1, 4), y = c(60, 75))

      ggplot(diamonds, aes(x=carat, y=depth)) + 
        geom_point()+
        geom_line(data = lineData, aes(x=x, y=y), color = "red")
    })

  })
)