在 Plotly/Shiny 中使用代理接口动态更改数据

Posted

技术标签:

【中文标题】在 Plotly/Shiny 中使用代理接口动态更改数据【英文标题】:Using Proxy Interface in Plotly/Shiny to dynamically change data 【发布时间】:2018-11-10 05:37:24 【问题描述】:

我想使用Proxy Interface 更新绘图中的数据(显示在 Shiny 应用程序的 plotlyOutput 中)。这是一个最小的 App.R 代码:

library(shiny)
library(plotly)

ui <- fluidPage(
    actionButton("update", "Test"),
    plotlyOutput("graphe")
)

server <- function(input, output, session) 
    output$graphe <- renderPlotly(
        p <- plot_ly(type="scatter",mode="markers")
        p <- layout(p,title="test")
        p <- add_trace(p, x=0,y=0,name="ABC_test",mode="lines+markers")
    )

    observeEvent(input$update, 
        proxy <- plotlyProxy("graphe", session) %>%
            plotlyProxyInvoke("restyle", list(x=0,y=1),0)
    )


shinyApp(ui, server)

当我运行它时,绘图会在 (0,0) 处显示一个点(根据需要),但是当我单击“测试”按钮时,该点不会移动到 (0,1)。我怎样才能做到这一点?

感谢您的任何回答。

【问题讨论】:

【参考方案1】:

restyle API 有点不稳定...我忘记了推理,但是像 xy 这样的数据数组需要双数组。我会这样做:

library(shiny)
library(plotly)

ui <- fluidPage(
  actionButton("update", "Test"),
  plotlyOutput("graphe")
)

server <- function(input, output, session) 
  output$graphe <- renderPlotly(
    plot_ly() %>%
      add_markers(x = 0, y = 0, name = "ABC_test") %>%
      layout(title = "test")
  )

  observeEvent(input$update, 
    plotlyProxy("graphe", session) %>%
      plotlyProxyInvoke("restyle", "y", list(list(1)), 0)
  )


shinyApp(ui, server)

【讨论】:

【参考方案2】:
library(shiny)

ui <- fluidPage(
    actionButton("update", "Test"),
    plotlyOutput("graphe")
)

server <- function(input, output, session) 

    output$graphe <- renderPlotly(
        plot_ly() %>%
            layout(title="test") %>%
            add_trace(x=runif(2), y=runif(2), name="ABC_test", type="scatter", mode="lines+markers")
    )

    observeEvent(input$update, 
        plotlyProxy("graphe", session, FALSE) %>%
            plotlyProxyInvoke("deleteTraces", list(as.integer(0))) %>%
            plotlyProxyInvoke("addTraces", list(x=runif(2),
                                                y=runif(2),
                                                name="ABC_test",
                                                type = 'scatter',
                                                mode = 'lines+markers'))
    )



shinyApp(ui, server)

【讨论】:

【参考方案3】:

奇怪的是addTraces不能只用一个点,而是用两个点。为了使它起作用,您可以两次添加相同的点。所以你可以试试这个:

ui <- fluidPage(
  actionButton("update", "Test"),
  plotlyOutput("graphe")
)

server <- function(input, output, session) 
  output$graphe <- renderPlotly(
    p <- plot_ly(type="scatter",mode="markers")
    p <- layout(p,title="test")
    p <- add_trace(p, x=0,y=0,name="ABC_test",mode="lines+markers")
  )

  observeEvent(input$update, 
    plotlyProxy("graphe", session) %>%
    plotlyProxyInvoke("deleteTraces", list(as.integer(1))) %>%
    plotlyProxyInvoke("addTraces", list(x=c(0, 0),y=c(1, 1),
                        type = 'scatter',
                        mode = 'markers'))
  )


shinyApp(ui, server)

【讨论】:

谢谢,但它不会更新当前跟踪的数据,而是添加另一个跟踪 @JulienVernay,你可以一行删除上一个点。查看修改。 它应该是list(as.integer(0)),因为情节跟踪是零索引的。 我在 github 上添加了 addTraces 错误报告。哇,我花了好几天的时间来解决这个错误。

以上是关于在 Plotly/Shiny 中使用代理接口动态更改数据的主要内容,如果未能解决你的问题,请参考以下文章

解决接口与动态代理绑定问题,实现rpc的最后一站

Spring AOP中的JDK和CGLib动态代理哪个效率更高?

Spring AOP中的JDK和CGLib动态代理哪个效率更高?

Java EE开发平台随手记5——Mybatis动态代理接口方式的原生用法

使用Jdk实现动态代理

动态代理