Here is a solution with plotly
. It does re-render the entire plot, but it's fast so perhaps will still meet your requirements. I think you'll see that introducing Plotly should not majorly disrupt your workflow.
Note that I use Plotly's WebGL function for speed. The example below is 100000 points. I've also included an example of how you would convert your existing ggplot2
object. For Plotly click events, 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)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…