如何将两个VennDiagram生成的韦恩图合并为网格对象并上下排列?
解决VennDiagram韦恩图上下排列展示的问题
你遇到的报错是因为VennDiagram::draw.pairwise.venn()返回的不是单个grob对象,而是grob元素的列表,而grid.pack需要传入单个grob,直接传列表就会触发"invalid 'grob'"错误。下面给你两种简单的解决方案来实现两个韦恩图的上下排列:
方案一:用gridExtra包快速实现(推荐)
gridExtra::grid.arrange()可以轻松处理多个grob的布局,只需要先把韦恩图的grob列表转换成单个grob对象即可:
# 加载所需包 library(VennDiagram) library(gridExtra) # 生成两个韦恩图 VennDiagram::draw.pairwise.venn( area1 = 100, area2 = 70, cross.area = 30, category = c("A1", "B1"), fill = c("#00204DFF", "#FFEA46FF") ) -> vg1 VennDiagram::draw.pairwise.venn( area1 = 120, area2 = 80, cross.area = 10, category = c("A2", "B2"), fill = c("#000004FF", "#FCFFA4FF") ) -> vg2 # 上下排列展示,nrow=2指定2行布局 grid.arrange(gTree(children = vg1), gTree(children = vg2), nrow = 2)
这里用gTree(children = vg1)把grob列表打包成单个grob对象,grid.arrange就能识别并布局了。
方案二:用原生grid包手动布局
如果你不想额外加载包,可以用grid的viewport系统手动设置布局:
library(VennDiagram) library(grid) # 先生成两个韦恩图(代码和之前一致) VennDiagram::draw.pairwise.venn( area1 = 100, area2 = 70, cross.area = 30, category = c("A1", "B1"), fill = c("#00204DFF", "#FFEA46FF") ) -> vg1 VennDiagram::draw.pairwise.venn( area1 = 120, area2 = 80, cross.area = 10, category = c("A2", "B2"), fill = c("#000004FF", "#FCFFA4FF") ) -> vg2 # 创建新绘图页面,设置2行1列的布局 grid.newpage() pushViewport(viewport(layout = grid.layout(2, 1))) # 绘制第一行的韦恩图 pushViewport(viewport(layout.pos.row = 1, layout.pos.col = 1)) grid.draw(gTree(children = vg1)) popViewport() # 绘制第二行的韦恩图 pushViewport(viewport(layout.pos.row = 2, layout.pos.col = 1)) grid.draw(gTree(children = vg2)) popViewport()
这个方法通过创建嵌套的viewport来划分区域,分别绘制两个图,灵活性更高。
为什么之前的方法会报错?
再次强调:draw.pairwise.venn()返回的是包含多个grob(比如圆圈、文本、填充等元素)的列表,而grid.pack、grid.frame这类函数要求传入单个grob对象。用gTree()把列表转换成单个组合grob,就能解决这个类型不匹配的问题了。
内容的提问来源于stack exchange,提问作者Konrad
相关产品推荐
相关产品推荐

