求助:基于ggplot与Shiny补充类Plotly交互式散点图两项功能
Solution: Add Legend Click Toggle and Hover Tooltips to Your Shiny Plot
Got it, let's add those two missing interactive features to your Shiny app! I've updated your code to include both clicking legend items to hide/show groups, and hover tooltips that display the exact X/Y values. Here's the full working code:
library(ggplot2) library(ggrepel) library(shiny) library(plotly) # Added for enhanced interactivity ui <- fluidPage( plotlyOutput("graph", height = 450, width = 900) ) server <- function(input, output) { # Reactive values to track zoom ranges and visible groups ranges <- reactiveValues(x = NULL, y = NULL) visible_groups <- reactiveValues(selected = unique(Data$Group)) # Creating sample Data Data <- data.frame( Group = c("Group 2","Group 1","Group 3","Group 2","Group 5","Group 4","Group 6", "Group 7","Group 4","Group 3","Group 1","Group 5","Group 6","Group 7", "Group 2","Group 4","Group 6","Group 7","Group 3","Group 1"), Fruit = c("apple","apple","apple","mango","apple","apple","apple","apple","mango","mango", "mango","mango","mango","mango","orange","orange","orange","orange","orange", "orange"), Percentage = c(68.46846847,77.35849057,72.72727273,26.12612613,76.31578947,62.79069767, 71.05263158,69.23076923,30.23255814,25,20.75471698,23.68421053,23.68421053, 23.07692308,5.405405405,6.976744186,5.263157895,7.692307692,2.272727273, 1.886792453) ) # Reactive filtered data based on visible groups filtered_data <- reactive({ Data[Data$Group %in% visible_groups$selected, ] }) # Handle legend click events to toggle group visibility observeEvent(event_data("plotly_legendclick"), { clicked_group <- event_data("plotly_legendclick")$name if(clicked_group %in% visible_groups$selected){ visible_groups$selected <- visible_groups$selected[visible_groups$selected != clicked_group] } else { visible_groups$selected <- c(visible_groups$selected, clicked_group) } }) # Handle double-click to zoom to selected brush area observeEvent(event_data("plotly_doubleclick"), { brush <- event_data("plotly_selected") if(!is.null(brush)){ ranges$x <- c(min(brush$x), max(brush$x)) ranges$y <- c(min(brush$y), max(brush$y)) } else { ranges$x <- NULL ranges$y <- NULL } }) # Render the interactive plot output$graph <- renderPlotly({ p <- ggplot(filtered_data(), aes(y = reorder(Fruit, Percentage), x = Percentage, color = Group, text = paste("Fruit:", Fruit, "<br>Percentage:", round(Percentage, 2), "%"))) + geom_point(size = 4) + scale_x_continuous(limits = c(0, 100)) + theme(panel.grid.major.y = element_line(color = "gray90", size = 0.7), panel.background = element_blank(), strip.background = element_blank(), panel.border = element_rect(color = "black", fill = NA, size = 1)) + labs(y = "", x = "% of people", color = "") # Convert to plotly and add zoom logic ggplotly(p, tooltip = "text") %>% layout(dragmode = "select", # Enable box selection xaxis = list(range = ranges$x), yaxis = list(range = ranges$y)) }) } shinyApp(ui = ui, server = server)
Key Changes Explained:
Mouse Hover Tooltips:
- Added a
textaesthetic in the ggplot call that formats hover content to show both the fruit name and rounded percentage value. - Used
ggplotly(p, tooltip = "text")to render the plot with custom, clean hover tooltips that display this formatted text.
- Added a
Legend Click to Hide/Show Groups:
- Created a
visible_groupsreactive value to track which groups are currently displayed. - Added an observer for
plotly_legendclickevents: when a legend item is clicked, the code toggles that group's visibility by adding/removing it from the tracked list. - A
filtered_datareactive filters the original dataset to only include visible groups before plotting.
- Created a
Retained Box-Select + Double-Click Zoom:
- Set
dragmode = "select"in the plotly layout to enable box selection for zooming. - Added an observer for
plotly_doubleclickevents: when you double-click after selecting a box, the plot zooms to that area; double-clicking without a selection resets the zoom.
- Set
This implementation gives you all three requested interactive features, with a Plotly-like experience while keeping your original ggplot styling intact.
内容的提问来源于stack exchange,提问作者Vedha Viyash
相关产品推荐
相关产品推荐

