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

生成ggplotly对象后能否修改悬停文本?韦恩图场景问询

问题

我有三个农场的水果、蔬菜、浆果品类数据,想用韦恩图对比各农场的品类差异,同时展示两两农场或所有农场的共同品类类型。目前通过ggvenn生成韦恩图并转为ggplotly对象后,悬停时显示的是数据点列表,我希望将其改为显示共同品类分组(如B、C农场共同的“Vegetables, Berries”),请问能否在生成ggplotly对象后修改以实现该效果?

附原始代码:

library(ggvenn)
library(plotly)
# Fruits
fruits <- c("Apple", "Banana", "Orange", "Mango", "Pineapple", "Peach", "Pear", "Grapefruit", "Lemon", "Kiwi")

# Vegetables
vegetables <- c("Carrot", "Broccoli", "Cauliflower", "Spinach", "Kale", "Potato", "Onion", "Garlic", "Cucumber", "Tomato")

# Berries
berries <- c("Strawberry", "Blueberry", "Raspberry", "Blackberry", "Cranberry", "Gooseberry", "Elderberry", "Mulberry", "Boysenberry", "Currant")

fvb <- c(fruits, vegetables, berries)
set.seed(344)
vennda <- list("A" = sample(fvb, 10),
     "B" = sample(fvb, 10),
     "C" = sample(fvb, 10))

gg <- ggvenn(vennda)
ggp <- ggplotly(gg)
ggp

解决方案

可以通过以下步骤实现需求:

  • 建立元素与品类的映射关系,方便快速查询归属
  • 提取韦恩图各区域的元素集合,计算对应品类类型
  • 替换ggplotly对象的悬停文本内容

修改后的完整代码如下:

library(ggvenn)
library(plotly)
library(dplyr)
library(purrr)

# 1. 建立元素-品类映射表
category_map <- tibble(
  item = c(fruits, vegetables, berries),
  category = c(rep("Fruits", length(fruits)),
               rep("Vegetables", length(vegetables)),
               rep("Berries", length(berries)))
)

# 原始数据生成
fruits <- c("Apple", "Banana", "Orange", "Mango", "Pineapple", "Peach", "Pear", "Grapefruit", "Lemon", "Kiwi")
vegetables <- c("Carrot", "Broccoli", "Cauliflower", "Spinach", "Kale", "Potato", "Onion", "Garlic", "Cucumber", "Tomato")
berries <- c("Strawberry", "Blueberry", "Raspberry", "Blackberry", "Cranberry", "Gooseberry", "Elderberry", "Mulberry", "Boysenberry", "Currant")
fvb <- c(fruits, vegetables, berries)
set.seed(344)
vennda <- list("A" = sample(fvb, 10),
               "B" = sample(fvb, 10),
               "C" = sample(fvb, 10))

# 2. 生成韦恩图并提取区域数据
gg <- ggvenn(vennda)
venn_data <- gg$data

# 3. 计算每个区域的共同品类,构建新悬停文本
venn_data <- venn_data %>%
  mutate(
    category_group = map_chr(items, function(x) {
      # 提取当前区域元素对应的品类,去重后拼接
      unique_cats <- category_map %>% filter(item %in% x) %>% pull(category) %>% unique()
      paste(unique_cats, collapse = ", ")
    }),
    hover_text = paste0("分组: ", name, "\n共同品类: ", category_group)
  )

# 4. 替换ggplotly的悬停文本
ggp <- ggplotly(gg, tooltip = "text")
for (i in seq_along(ggp$x$data)) {
  trace_name <- ggp$x$data[[i]]$name
  if (!is.null(trace_name)) {
    matched_text <- venn_data %>% filter(name == trace_name) %>% pull(hover_text)
    if (length(matched_text) > 0) {
      ggp$x$data[[i]]$text <- matched_text
      ggp$x$data[[i]]$hoverinfo <- "text"
    }
  }
}

# 查看最终效果
ggp

代码说明

  • category_map:统一管理元素与品类的对应关系,避免重复判断
  • venn_data:从ggvenn生成的ggplot对象中提取各区域的分组名称、元素列表等核心数据
  • category_group:对每个区域的元素去重后提取所属品类,转换为易读的字符串格式
  • 最后遍历plotly的每个图层,将原始悬停文本替换为包含分组名称和共同品类的自定义文本

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 02:33:11