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

在ggplotly散点图自定义数据标签:悬停显示Species及点击持久化

Solution for Custom Hover Tooltips & Persistent Click Labels in ggplotly + Shiny (Iris Dataset)

Hey there! I've got you covered on both your core and extra requirements for your Shiny app using the iris dataset. Let's break this down with a complete, annotated code example that includes the extrafont setup you mentioned.

Core Requirement: Show Species on Hover Instead of Default X/Y Values

To replace the default hover tooltips with just the Species name, we'll use ggplot's aes(text = ...) to define custom hover text, then tell ggplotly to use that text for tooltips with tooltip = "text".

Extra Requirement: Persistent Labels on Click

For click-to-show-persistent labels, we'll leverage Shiny's event_data("plotly_click") to capture the clicked point's data, then add a geom_label layer that only displays for the selected point.

Full Shiny App Code

library(shiny)
library(ggplot2)
library(plotly)
library(extrafont)

# Configure extrafont (run these once to set up your fonts)
# font_import()
# loadfonts(device = "win") # Adjust based on your OS (win/mac/linux)

ui <- fluidPage(
  titlePanel("Iris Dataset: Custom Hover & Click Labels"),
  plotlyOutput("iris_plot"),
  # Optional: Add a reset button to clear persistent labels
  actionButton("reset_label", "Clear Clicked Label")
)

server <- function(input, output) {
  
  # Reactive value to store data from the clicked point
  clicked_point <- reactiveVal(NULL)
  
  output$iris_plot <- renderPlotly({
    # Base ggplot with custom hover text configuration
    p <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) +
      geom_point(
        aes(color = Species, text = paste("Species:", Species)),
        size = 3
      ) +
      theme_minimal() +
      theme(text = element_text(family = "Segoe UI")) # Use your preferred extrafont here
    
    # Add persistent label if a point has been clicked
    if (!is.null(clicked_point())) {
      p <- p +
        geom_label(
          data = clicked_point(),
          aes(label = Species),
          nudge_x = 0.2, nudge_y = 0.2,
          color = "black", fontface = "bold",
          fill = alpha("white", 0.8)
        )
    }
    
    # Convert to plotly and enforce custom tooltip
    ggplotly(p, tooltip = "text") %>%
      event_register("plotly_click") # Ensure click events are captured
  })
  
  # Capture plotly click events and update reactive value
  observeEvent(event_data("plotly_click"), {
    click_info <- event_data("plotly_click")
    # Plotly uses 0-based indexing, so add 1 to match iris's 1-based rows
    selected_row <- iris[click_info$pointNumber + 1, ]
    clicked_point(selected_row)
  })
  
  # Reset persistent label when button is clicked
  observeEvent(input$reset_label, {
    clicked_point(NULL)
  })
}

shinyApp(ui = ui, server = server)

Key Details Explained

  • Custom Hover Text: The aes(text = paste("Species:", Species)) inside geom_point defines exactly what appears on hover. The tooltip = "text" argument in ggplotly() tells plotly to use this custom text instead of the default x/y coordinates.
  • Persistent Click Labels: The clicked_point reactive value stores the full row of data from the clicked point. We check if this value exists, and if so, add a geom_label that stays visible until another point is clicked or the reset button is pressed.
  • Extrafont Integration: The theme(text = element_text(family = "Segoe UI")) line uses a font installed via extrafont—replace "Segoe UI" with any font you've set up using font_import() and loadfonts().

Quick Tweaks You Might Want

  • If you want to keep multiple persistent labels (not just one), modify clicked_point to store a dataframe instead of a single row, then append new clicked points to it.
  • Adjust nudge_x and nudge_y in geom_label to move the label away from the point and avoid overlap.

内容的提问来源于stack exchange,提问作者firmo23

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:55:56