R 闪闪发亮:在 isolate 和 observeEvent 中仍然发生失效

R shiny with plotly: invalidation still occurring inside isolate and observeEvent

考虑一个简单的绘图散点图,该散点图取决于用户选择(通过 selectInput),用户选择要在特定轴上绘制的变量。我们希望通过单击按钮来更新绘图,而不是当用户与 selectInput 交互时。因此,我们将绘图更新逻辑包装在一个依赖于按钮的 observeEvent 中。 observeEvent 更新包含绘图的 reactiveValues 对象。 (这个例子使用 reactiveValues 因为我们用 ggplot 和 plotly 图来证明这一点。)

当应用程序为 运行 时,在单击 actionButton 之前,从 selectInput 更改所选变量不会更新绘图(如预期的那样)。但是,在 actionButton 单击一次后,对 selectInput 的任何进一步更改都会立即使 plotly plot 无效并导致其重新呈现。 ggplot 图不会发生此行为(仅在单击 actionButton 时更新)。

我也试过在 isolate 中包装定义 plotly plot 的反应值,并创建对 input$update_plts 按钮的显式依赖,但这没有什么区别。

library(shiny)
library(ggplot2)
library(plotly)

ui <- {
    fluidPage(
        selectInput('select_xvar', label = 'select x var', choices = names(mtcars)),
        actionButton('update_plts', 'Update plots'),
        plotOutput('plt1'),
        plotlyOutput('plt2')
    )
}

server <- function(input, output, session) {
    
    val <- reactiveValues(
        plt1 = ggplot(mtcars) +
            geom_point(aes(x = wt, y = mpg)
        ),
        plt2 = plot_ly(mtcars,
            x = ~wt,
            y = ~mpg
        )
    )
    
    observeEvent(input$update_plts, {
        val$plt1 = ggplot(mtcars) +
            geom_point(aes_string(
                x = input$select_xvar,
                y = 'mpg'
            ))
        val$plt2 = plot_ly(mtcars,
            x = ~get(input$select_xvar),
            y = ~mpg)
    })
    
    output$plt1 <- renderPlot(val$plt1)

    # initial attempt with no isolate
    # output$pl2 <- renderPlotly(val$plt2)

    # second attempt with isolate, still invalidates instantaneously
    output$plt2 <- renderPlotly({
        input$update_plts
        isolate(val$plt2)
    })
}

shinyApp(ui, server)

知道为什么 plotly 会出现这种情况吗?我能找到的唯一参考是 closed Github issue that is apparently unresolved.

不知道为什么,但是当您 isolateplot_ly 调用中输入时,它会按预期工作:

val$plt2 = plot_ly(mtcars,
                   x = ~get(isolate(input$select_xvar)),
                   y = ~mpg)

然后您可以从 renderPlotly 中删除 isolateactionButton:

output$plt2 <- renderPlotly(val$plt2)