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

如何在R语言中绘制符合要求的分类群韦恩图?

问题描述
  • 用R绘制韦恩图对比两种方法得到的科分类群,需展示仅MethodA、仅MethodB及重叠的科,但当前科名超出图边界
  • 需求扩展:生成门(Phylum)级带科名的韦恩图,同时支持一组图的批量查看或单张单独查看

一、修复基础韦恩图的标签溢出问题

1. 修正原数据语法错误

原代码中MethodA的"Balistidae"后缺少逗号,先修正该问题:

MethodA <- list("Achiropsettidae",
"Acipenseridae",
"Acropomatidae",
"Adrianichthyidae",
"Agonidae",
"Akysidae",
"Albulidae",
"Alepisauridae",
"Alepocephalidae",
"Alestiidae",
"Alopiidae",
"Amarsipidae",
"Ambassidae",
"Amblycipitidae",
"Amblyopsidae",
"Amiidae",
"Ammodytidae",
"Amphiliidae",
"An-Ap",
"Anabantidae",
"Anablepidae",
"Anacanthobatidae",
"Anarhichadidae",
"Anguillidae",
"Anomalopidae",
"Anoplogastridae",
"Anoplopomatidae",
"Anostomidae",
"Anotopteridae",
"Antennariidae",
"Aphredoderidae",
"Aphyonidae",
"Apistidae",
"Aploactinidae",
"Aplocheilidae",
"Aplodactylidae",
"Apogonidae",
"Apteronotidae",
"Bagridae",
"Balistidae",  # 补上缺失的逗号
"Balitoridae",
"Banjosidae",
"Barbourisiidae",
"Bathyclupeidae",
"Bathydraconidae",
"Bathylagidae",
"Bathylutichthyidae",
"Bathymasteridae",
"Batrachoididae",
"Bedotiidae",
"Belonidae",
"Bembridae",
"Berycidae",
"Blenniidae")

MethodB <- list("Abyssocottidae",
            "Acanthuridae",
            "Acestrorhynchidae",
            "Achiridae","Aphredoderidae",
            "Aphyonidae",
            "Apistidae",
            "Aploactinidae",
            "Aplocheilidae",
            "Aplodactylidae",
            "Apogonidae",
            "Apteronotidae")

2. 优化标签展示避免溢出

方法1:调整基础韦恩图参数

通过缩小字号、扩大边距等方式适配长标签:

library(VennDiagram)
library(grid)

# 生成韦恩图对象,优化参数适配长标签
v <- venn.diagram(list(MethodA=MethodA, MethodB=MethodB),
                  fill = c("transparent", "blue"),
                  alpha = c(0.5, 0.5), 
                  cat.cex = 1.2, 
                  cex=0.35,  # 进一步缩小标签字号
                  filename=NULL, 
                  main = "Family Level Venn Diagram", 
                  main.cex = 1.5, 
                  lty=c(1,2),
                  col=c("lightblue","navy"), 
                  sub = "Year: 2000", 
                  ext.percent=0.1,  # 扩大区域占比
                  euler.d=TRUE, 
                  scaled=TRUE,
                  margin = 0.15)  # 增加图边距

# 替换各区域的科名标签
v[[5]]$label <- paste(setdiff(MethodA, MethodB), collapse="\n")
v[[6]]$label <- paste(setdiff(MethodB, MethodA), collapse="\n")
v[[7]]$label <- paste(intersect(MethodA, MethodB), collapse="\n")

# 绘制图
grid.newpage()
grid.draw(v)

方法2:交互式韦恩图(推荐)

用plotly实现交互式查看,鼠标悬停即可查看对应区域的所有科名,彻底避免溢出:

library(plotly)

# 计算各区域的科集合
only_A <- setdiff(MethodA, MethodB)
only_B <- setdiff(MethodB, MethodA)
both <- intersect(MethodA, MethodB)

# 绘制交互式韦恩图
fig <- plot_ly(
  type = "venn",
  set = c("MethodA", "MethodB"),
  value = c(length(only_A), length(only_B), length(both)),
  text = list(
    paste(only_A, collapse="<br>"),
    paste(only_B, collapse="<br>"),
    paste(both, collapse="<br>")
  ),
  hoverinfo = "text"
) %>%
  layout(title = list(text="Family Level Venn Diagram", font=list(size=18)))

fig

二、门(Phylum)级韦恩图实现

假设已有科对应的门分类数据,按以下步骤生成门级韦恩图:

1. 构建科-门映射表

替换示例数据为你的真实分类信息:

# 示例科-门映射,实际替换为你的数据
taxa_map <- data.frame(
  family = c(unlist(MethodA), unlist(MethodB)),
  phylum = rep("Chordata", length(c(unlist(MethodA), unlist(MethodB))))
)

# 按门分组,提取每个门下的MethodA/MethodB科集合
phylum_venn_data <- lapply(split(taxa_map$family, taxa_map$phylum), function(fams) {
  list(
    MethodA = intersect(fams, unlist(MethodA)),
    MethodB = intersect(fams, unlist(MethodB))
  )
})

2. 批量生成支持全部/单独查看的图

方式1:静态图批量输出

library(gridExtra)

# 定义单门韦恩图绘制函数
plot_phylum_venn <- function(phylum_name, data) {
  v <- venn.diagram(data,
                    fill = c("transparent", "blue"),
                    alpha = 0.5,
                    cat.cex = 1.2,
                    cex=0.4,
                    filename=NULL,
                    main = paste(phylum_name, " - Family Venn"),
                    main.cex = 1.3,
                    margin = 0.15)
  grid.draw(v)
}

# 生成所有门的组合图(用于全部查看)
pdf("phylum_venns_all.pdf", width=12, height=8)
grid.arrange(grobs=lapply(names(phylum_venn_data), function(p) {
  grid.grabExpr(plot_phylum_venn(p, phylum_venn_data[[p]]))
}), ncol=2)
dev.off()

# 单独保存每个门的图(用于单张查看)
for(p in names(phylum_venn_data)) {
  png(paste0(p, "_venn.png"), width=800, height=600)
  plot_phylum_venn(p, phylum_venn_data[[p]])
  dev.off()
}

方式2:交互式网页应用(灵活切换查看)

用shiny实现网页端的单图/全图切换查看:

library(shiny)
library(VennDiagram)
library(grid)

ui <- fluidPage(
  titlePanel("Phylum Level Venn Diagrams"),
  sidebarLayout(
    sidebarPanel(
      selectInput("phylum_select", "选择门", choices = names(phylum_venn_data), selected = names(phylum_venn_data)[1]),
      actionButton("view_all", "查看全部门的图")
    ),
    mainPanel(
      uiOutput("venn_plot")
    )
  )
)

server <- function(input, output) {
  # 单张门的韦恩图
  output$single_plot <- renderPlot({
    plot_phylum_venn(input$phylum_select, phylum_venn_data[[input$phylum_select]])
  })
  
  # 所有门的组合图
  output$all_plots <- renderPlot({
    grid.arrange(grobs=lapply(names(phylum_venn_data), function(p) {
      grid.grabExpr(plot_phylum_venn(p, phylum_venn_data[[p]]))
    }), ncol=2)
  })
  
  # 根据按钮切换展示内容
  output$venn_plot <- renderUI({
    if(input$view_all > 0) {
      plotOutput("all_plots", width="100%", height="800px")
    } else {
      plotOutput("single_plot", width="800px", height="600px")
    }
  })
}

shinyApp(ui, server)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 17:47:00