更新Shiny中没有重新渲染的大块地块

时间:2016-12-19 23:44:50

标签: javascript r ggplot2 shiny

一般目标

我希望能够使用RShiny快速绘制来自R的大量数据,然后进行少量修改或添加,而无需重新渲染所有绘制的数据。

特定任务

  1. 在散点图中绘制大量点(<100 000)。我可以在此任务中使用短暂(<5秒)但可感知的延迟。
  2. 响应鼠标单击,检测最近绘制的点。
  3. 使用从与此点相关的数据查询的某些信息,突出显示少量其他点(&lt; 10)。我希望这是瞬间的。
  4. 当前方法

    我目前使用ggplot2和RShiny制作应用程序以帮助进行数据分析。总的来说,我对这种组合非常满意。理想情况下,解决方案将允许我仍然主要使用这些工具。

    仅使用RShiny和ggplot2的内置功能,我完成任务没有任何问题,除了之外,步骤3无法独立完成,无需重做第1步。我的理解是它无法更新或覆盖ggplot2图而无需重新整体渲染它们。

    所以,我正在寻找的是按照偏好的降序实现我的总体目标之一:

    1. 一种覆盖或修改ggplot2图而无需重新渲染的方法。
    2. 扩展或分叉或类似的基于R的ggplot2,允许这样做。
    3. ggplot2的替代方案,同样易于与RShiny和R数据集成,可以实现这一点。也许是现有javascript库的一些接口?我仍然希望能够使用我熟悉的所有RShiny机器来操纵和交互我的情节。
    4. 我对js有一些了解,但是不想像d3那样学习完成这么小的任务。 (如果可以使用一小部分d3或js来做到这一点,那就太好了!)能够在ggplot2图上有效地绘制svg,但是使用相同的坐标系。

      我知道this question,但提供的解决方案特定于时间序列数据。

1 个答案:

答案 0 :(得分:0)

以下是plotly的解决方案。它确实重新渲染整个情节,但它很快,所以或许仍然可以满足您的要求。我想你会发现引入Plotly不会严重破坏你的工作流程。

请注意,我使用Plotly的WebGL function来提高速度。以下示例为100000点。我还提供了一个如何转换现有ggplot2对象的示例。对于Plotly点击事件,see this

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

ui <- fluidPage(

  titlePanel("Highlight nearby points"),

  sidebarLayout(
    sidebarPanel(width=3,
      p("Click on a point. Nearby points will be highlighted.")
    ),

    mainPanel(
      plotlyOutput("plot")
    )
  )
)

# Data
df <- tibble(x = runif(1e+05,1,100), y = runif(1e+05,1,100))

server <- function(input, output, session) {

  output$plot <- renderPlotly({

    # Gather click data
    event.data <- event_data("plotly_click")

    # Plotly object
    p <- plot_ly(df, x = ~x, y = ~y, type = "scatter", mode = "markers") 

    # Alternative: use existing ggplot

    # gg <- ggplot(df, aes(x = x, y = y)) +
    #   geom_point()
    # 
    # p <- plotly_build(gg)

    # End alternative

    # Check for click data
    if(!is.null(event.data)) {

      # If click data exists, create new markers based on range criteria and use a different color
      d <- filter(df,
                  x < event.data$x+10 & x > event.data$x-10,
                  y < event.data$y+10 & y > event.data$y-10)
      p <- add_markers(p, data = d, color = I("red"))

    }

    # Use webGL for faster ploting of many points
    p %>% toWebGL()

  })
}

# Run the application 
shinyApp(ui = ui, server = server)