在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))insidegeom_pointdefines exactly what appears on hover. Thetooltip = "text"argument inggplotly()tells plotly to use this custom text instead of the default x/y coordinates. - Persistent Click Labels: The
clicked_pointreactive value stores the full row of data from the clicked point. We check if this value exists, and if so, add ageom_labelthat 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 usingfont_import()andloadfonts().
Quick Tweaks You Might Want
- If you want to keep multiple persistent labels (not just one), modify
clicked_pointto store a dataframe instead of a single row, then append new clicked points to it. - Adjust
nudge_xandnudge_yingeom_labelto move the label away from the point and avoid overlap.
内容的提问来源于stack exchange,提问作者firmo23
相关产品推荐
相关产品推荐

