我正在尝试构建一个闪亮的应用程序,可以通过交互方式更改绘图。 我希望该图在毫秒级别内更改,并且由于更改仅涉及添加一些点,因此这实际上是可能的。
可重现的示例包含了这个想法的抽象。第一个示例绘制了一个散点图,我可以交互式地更改点的数量。 这基本上立即发生。 我将把这部分图称为"反应层"。
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的背景,通过使其成为反应性UI来为output$plotx
。但我还没有成功地操纵HTML和CSS。
任何帮助都会感激。非常感谢!