我正在尝试构建一个闪亮的应用程序,我可以在其中交互式地更改绘图。我希望绘图在几毫秒内发生变化,并且由于变化仅包括添加一些点,这实际上是可能的。
可重现的示例包含此想法的抽象。第一个示例绘制了一个散点图,我可以交互地更改点数。这基本上立即发生。我将这部分图称为“反应层”。
library(shiny)
ui <- fluidPage(
sliderInput(inputId = "slider_input", label = "Reactive values:", min = 1, max = 100, value = 10),
plotOutput(outputId = "plotx")
)
quick_server <- function(input, output, session){
output$plotx <- renderPlot({
# reactive layer
plot(
x = sample(x = -4:4, size = input$slider_input, replace = T),
y = sample(x = -4:4, size = input$slider_input, replace = T)
)
})
}
shinyApp(ui = ui, server = quick_server)
问题是,我想要交互式更改的图始终包含许多数据点的“缓慢非反应层”,这些数据点不反应并且永远不会改变。由于该数据集的大小以及renderPlot()
总是重新绘制它,我交互式地改变“反应层”的速度急剧下降。
library(shiny)
ui <- fluidPage(
sliderInput(inputId = "slider_input", label = "Reactive values:", min = 1, max = 100, value = 10),
plotOutput(outputId = "plotx")
)
slow_server <- function(input, output, session){
base_data <- reactiveVal(value = data.frame(x = rnorm(n = 200000), y = rnorm(n = 200000)))
output$plotx <- renderPlot({
# slow non reactive layer
plot(x = base_data()$x, y = base_data()$y)
# reactive layer
points(
x = sample(x = -4:4, size = input$slider_input, replace = T),
y = sample(x = -4:4, size = input$slider_input, replace = T),
col = "red",
cex = 5,
pch = 19
)
})
}
shinyApp(ui = ui, server = slow_server)
由于基础数据和结果图(这里是点云)永远不会改变,这是相当令人烦恼的renderPlot()
总是重新绘制所有内容(两个“层”)。有没有办法“隔离”从非反应数据集创建的图?这样不具有反应性的层就不会被重新绘制?
我已经尝试使用 ggplot2 并创建一个稳定的层
big_data_frame <- data.frame(x = rnorm(n = 200000), y = rnorm(n = 200000))
steady_layer <- reactiveVal(value = geom_point(data = big_data_frame, mapping = aes(x = x, y = y))
然后创建这样的情节
output$plotx <- renderPlot({
small_df <-
data.frame(
x = sample(x = -4:4, size = input$slider_input, replace = T),
y = sample(x = -4:4, size = input$slider_input, replace = T)
)
ggplot() +
steady_layer() +
geom_point(data = small_df, mapping = aes(x = x, y = y)
})
但这并没有帮助,因为重新绘制过程需要时间而不是创建 ggplot 图层本身。
尽管我可以想象解决方案可能是创建大图的 .png 并将其用作 HTML 和 CSS 的背景output$plotx
通过使其成为反应式 UI,我无法成功操作 HTML 和 CSS。
任何帮助表示赞赏。非常感谢!