You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:基于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:

  1. Mouse Hover Tooltips:

    • Added a text aesthetic 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.
  2. Legend Click to Hide/Show Groups:

    • Created a visible_groups reactive value to track which groups are currently displayed.
    • Added an observer for plotly_legendclick events: when a legend item is clicked, the code toggles that group's visibility by adding/removing it from the tracked list.
    • A filtered_data reactive filters the original dataset to only include visible groups before plotting.
  3. Retained Box-Select + Double-Click Zoom:

    • Set dragmode = "select" in the plotly layout to enable box selection for zooming.
    • Added an observer for plotly_doubleclick events: when you double-click after selecting a box, the plot zooms to that area; double-clicking without a selection resets the zoom.

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:50:37