资讯动态

集合关系图怎么做到“面积即数量“:从韦恩图到 UpSet 的取舍

发布时间:2026/10/14 2:45:19 来源:尧图企业网站定制
想画一个韦恩图时真正卡住人的通常不是画圆而是三个技术问题手工画的圆面积能不能反映真实数量集合超过 3 个怎么办导出到论文或印刷品时字体和矢量怎么处理这篇不聊工具怎么挑只解决这三个问题顺带给出可以直接跑的代码。一、先分清两种图选错方向后面全白做同样叫韦恩图实际是两类东西逻辑示意图数据驱动图圆的面积无关紧要只是版面代表子集大小绘制方式手工摆放、调透明度由代码根据数值计算圆心与半径适用场景会议讨论、方案说明、PPT论文、数据报告、严谨表达典型工具画布/白板类工具、演示软件matplotlib-venn、eulerr关键判断如果读者可能从圆的面积读出数量信息就必须用第二类。手工画的圆面积是随手的读者却会当真——这是集合图最常见的误导来源。反过来说如果这张图只是讲职责边界需求重叠区这类结构关系用第一类就够了硬套数据驱动是自找麻烦。二、数据驱动的两种实现路径路径 APython matplotlib-venn这个库的定位是area-weighted two- and three-circle venn diagrams即按面积加权绘制两圆和三圆韦恩图。两集合subsets传三元组(Ab, aB, AB)分别对应只在 A、只在 B、A 与 B 的交集。frommatplotlib_vennimportvenn2# 只在 A 10只在 B 5交集 3venn2(subsets(10,5,3),set_labels(A,B))三集合subsets传七元组(Abc, aBc, ABc, abC, AbC, aBC, ABC)命名规则是属于该区域的集合用大写不属于的用小写frommatplotlib_vennimportvenn3# 顺序只在A、只在B、AB交、只在C、AC交、BC交、ABC交venn3(subsets(1,1,2,1,2,2,3),set_labels(销售,产品,研发))自 0.7 版起也可以直接把集合对象交给它去算不必自己统计venn2([{a,b,c,d},{d,e,f}])必须知道的一条硬限制官方文档原话“for a three-circle venn diagram it is not in general possible to achieve exact correspondence between the required set sizes and region areas”——三圆韦恩图在一般情况下无法让七个区域的面积与集合大小精确对应只能尽量接近。这不是库的实现问题是几何约束三个圆的位置和半径只有有限的自由度而你要同时满足七个区域面积。数据稍微极端一点比如某个区域为 0、或某个集合远大于其他画出来就会明显失真。如果只想要结构、不在乎面积用配套的非加权版本venn2_unweighted/venn3_unweighted它会画出标准等大的圆至少版面稳定不会再让读者误读面积。一个容易踩的坑某个区域的数量为 0 时该区域的标注不会显示。这不是 bug而是那个区域在几何上塌缩成了点或不存在没有位置放标签。遇到这种情况要么在正文里说明某区域为空要么改用 UpSet。路径 BR eulerr如果对面积准确度要求高或者集合数是 3~4 个eulerr是更合适的选择。它的包描述是Area-Proportional Euler and Venn Diagrams思路和前面的库不同用残差平方和stress去拟合各区域面积并且不限于圆可以用椭圆。椭圆比圆多出的自由度正好用来逼近那七个区域的面积约束所以能明显缓解三集合失真的问题。它还会报告拟合的质量指标你可以据此判断这张图能不能用来支撑结论——如果 stress 很大就该老实换图而不是硬发。三、超过 3 个集合换图不要硬凑4 个以上的集合韦恩图的可读性会迅速崩塌圆与圆的交叠区域太多且几何上更不可能精确。相关社区的经验是超过 4 个集合就优先考虑 UpSet 图。UpSet 图把集合和交集拆成两个维度下方矩阵表示这次统计的是哪几个集合的交集上方柱状图表示该交集的大小。集合再多也不会乱。Python 侧用upsetplot它接受两种输入方式fromupsetplotimportfrom_memberships,plotfrommatplotlibimportpyplotasplt# 按每个数据点属于哪些集合描述data 给出各组合的数量examplefrom_memberships([[],[cat2],[cat1],[cat1,cat2],[cat0],[cat0,cat2],[cat0,cat1],[cat0,cat1,cat2]],data[56,283,1279,5882,24,90,429,1957],)plot(example)plt.show()如果数据本来就是pandas的布尔列每列一个集合可以直接按类别分组后交给它不必手工整理成员关系。R 侧的对应实现是ComplexUpset基于ggplot2主题和配色能跟着现有图表体系统一。取舍原则集合 ≤ 2 个且需要精确比例 → 韦恩图圆能精确表达集合 3 个需要精确比例 →eulerr椭圆拟合或改 UpSet集合 3 个只要结构 → 非加权韦恩图集合 ≥ 4 个 → UpSet不要犹豫四、导出与排版两个高频问题1. SVG 里的字变成路径没法再编辑matplotlib默认把文字转成路径写进 SVG用 Illustrator 或 Inkscape 打开后无法再改字。如果交付方需要二次编辑改这个全局设置frommatplotlibimportpyplotasplt,rcParams rcParams[svg.fonttype]none# 文字以 text 形式写入保留可编辑性代价是文件在其他机器上打开时依赖字体缺字体就会替换。稳妥做法是随文件一起交付字体或同时导出一份 PDF 备案。2. 中文字体不生效matplotlib默认字体没有中文字形会显示为方框。指定字体并关掉负号渲染问题rcParams[font.sans-serif][Noto Sans CJK SC,Source Han Sans SC,SimHei]rcParams[axes.unicode_minus]False用ax参数可以精细控制版式而不是依赖当前坐标系fig,axplt.subplots(figsize(6,5),dpi200)venn2(subsets(10,5,3),set_labels(A,B),axax)fig.savefig(venn.svg,bbox_inchestight)dpi只影响位图导出SVG/PDF 是矢量、不受影响如果最终要插入 Word 或公众号再单独导一份 2x/3x 的透明背景 PNG。3. 格式怎么选用途格式理由论文、印刷、LaTeXPDF / SVG矢量放大不糊需要交付方二次编辑SVG配svg.fonttypenone文字保留为文本节点网页、公众号、PPTPNG2x/3x透明底兼容性稳妥需要现场演示改数据代码与数据一起交付改数字即重出图避免手工返工五、避坑清单不要让面积说谎。手工画的圆面积不代表数量除非你用代码生成。这比图不好看严重得多。三集合别迷信精确。几何上做不到就是做不到eulerr会告诉你拟合质量matplotlib-venn官方也直接说明了这一点。每个区域都要有信息。空白区域会让读者怀疑你没想清楚宁可标注无重叠。颜色优先考虑可读性。用透明度区分交叠避免红绿并置色觉障碍不友好可用边框、纹理或灰度增强区分。集合多就换图。4 个以上优先 UpSet 或拆成多张局部图。交付格式与场景匹配。印刷要矢量屏幕传播要高分辨率位图两者不能互相替代。六、小结集合关系图的核心判断只有一条这张图的面积要不要承载数量信息。不承载 → 用画布或演示软件手工排版即可几十秒的事重点是版面清楚。承载 → 交给代码两集合用圆可以精确表达三集合要接受尽量接近集合再多就换 UpSet。工具在这里的位置其实很靠后讨论阶段用画布类工具例如诺智白板 NuromBoard 这类把白板、流程图、思维导图放在同一张画布上的实现适合边讨论边改正式出图无论用 Python 还是 R最终都要落到代码上才能保证面积可信。参考资料matplotlib-venn官方文档与 README含三圆精确对应不可行的说明、venn2/venn3参数定义upsetplot官方文档from_memberships与plot用法CRANeulerr包Area-Proportional Euler and Venn DiagramsCRANComplexUpset包基于ggplot2的 UpSet 实现Lex et al.,UpSet: Visualization of Intersecting Sets, IEEE TVCG 2014说明以上均为开源项目官方文档与论文核对时间 2026 年 10 月。本文为个人实践记录未接受任何形式的赞助库的 API 与默认行为随版本变化请以实际安装版本的文档为准。附文中涉及的项目与工具名称性质文中出现位置matplotlib-venn开源Python§二、§四eulerr开源RCRAN§二upsetplot开源PythonBSD-3§三ComplexUpset开源RCRAN§三诺智白板NuromBoard商业 SaaS§六

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑