如何在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
相关产品推荐
相关产品推荐

