简单易懂的可视化魔法——用 R 的 venn 包画五组数据的文氏图

前言

如何画 Venn 图(温氏图、维恩图、维恩图解、范氏图、韦恩图)是老生常谈了,但是对于初学者上手还是有一定门槛,熟读 venn 包的文档进行实操后觉得其实还是比较简单,实现了一下基础的功能,把实战过程记录在此。

需求

我手里有几组研究相关的数据,分别来自八个不同的数据库,彼此有重叠的部分,想统计数据库之间重叠数据的量并以 venn 图的方式进行可视化。本来想直接扔八组数据作图的,上网查了n组数据作图的方案,发现可读性实在是太差1。正好经过统计发现其中四组数据各自的量偏少,合起来倒是能和其他四组数据的量相当,于是干脆做了合并处理,就变成了传统的五组数据作图了。

准备

一个用 Python 做了预处理的文件,格式大致如下:

groupname groupvalue
g1 A
g1 B
g2 A
... ...
g5 C
g5 D

其中第一列是组别,有五组,第二列是组别各自对应的数值,彼此有相同的部分。当然可以用 R 做数据预处理,不过这里省略基础部分,直接从成熟的数据开始处理。

参考网上的教程,包括:

【R作图】在R中绘制韦恩图的几种方法 和 一些漂亮的venn图

R绘图基础(五)文氏图vennDiagram

使用VennDiagram包绘制韦恩图

以及一个貌似是利用自己写的代码配合 matplotlib 绘图的库 tctianchi/pyvenn

方法包括 R 里面的 limma::vennDiagram, gplot::venn, venneuler, VennDiagram 和 python 里面的 pyvenn库,以及一些在线工具。

其中 limma 和 venneuler 只能画三组数据,不符合我的要求,另外大佬们的文章似乎有点过时,我看现在有些包应该没那么弱了吧。至于我为什么不用 python 的库,没有为什么,就像我今晚突然不想吃我爱吃的肥宅快乐餐一样。

然后发现了独立的 venn 包,上面的文章里提到2012年的时候找不到 venn 包了,但是我误打误撞在 google 首页就翻到了 venn 1.7 的文档,一看时间发布于2018年七月底2,就感觉很迷。研究了一会,感觉看进去了,那好吧就用它了!

操作

基础入门三步走

1
2
3
install.packages("venn") #安装
library(venn) #导入
?venn #查看文档

前面文档说了一堆,跳过了,直奔主题看五组数据怎么画。没错我就是这么功利而不求甚解。

直接看 Usage 里的 arguments

x - 单个数字(集合)或元模型公式,或包含设置值的列表,或包含布尔值的数据集。 关键词,可以扔 list 进去

snames - 包含每个集名称的可选参数。

ilabels - 打印每个交叉点的标签。 TRUE 是打印, FALSE 为否

counts - 每组交集的计数的数字向量。

ellipse - 尽可能将形状强制为椭圆。 TRUE 是把区域变成椭圆, FALSE 为否

zcolor - 自定义区域的颜色矢量,或“样式”的预定义颜色

opacity - 就是用数值调不透明度

size - 就是用数值调整绘图大小,以厘米为单位。

cexil - 就是用数值调整每个交集区域数值标签的字体大小免得看不清

cexsn - 就是用数值调整集合名称标签的字体大小

borders - 绘制所有交叉点边界 看不出来效果

(对不起,上面是我机翻+脑补的,因为实在懒得打字)

数据导入及基本作图

1
2
3
4
5
datasets <- read.table("/path/to/your/data.txt", header = TRUE, sep = '\t') #导入数据,数据格式见前文,路径自己填,数据包含表头, Tab 分隔
g1 = datasets$groupvalue[datasets$groupname == 'g1'] #把同 groupname 的 groupvalue 们归类到一个 factor 中,下略
...
x = list(g1,g2,g3,g4,g5) #将五组数据也就是五个 factor 放入一个 list 中
venn(x) #文氏图飞来!

出图。

太单调?来点高级的。

1
venn(x, snames = "G1,G2,G3,G4,G5", zcolor = "style", cexil = 1, cexsn = 0.8) #指定集合名称,设置默认的颜色风格,把交集区域数值标签字体改大到1,集合名称标签字体改成0.8

1
venn(x, snames = "G1,G2,G3,G4,G5", ellipse = TRUE, zcolor = "style", cexil = 1, cexsn = 0.8) #诸君,我喜欢椭圆

后记

以上就是此次玩弄 venn 包的过程,我自己的目的已经达到了,可以进行下一步的研究了。内容非常简单,我不写你们也能学会,希望大家不要因为我写的这堆乱七八糟的东西,反而看不懂了。对这个包有更深兴趣的朋友可以自行查阅文档里其他功能的介绍。

venn 包支持最高七组数据的文氏图绘制,你们可以 venn(7) 简单看看效果。

参考


  1. 7维韦恩图 7-set Venn Diagram | 知乎专栏↩︎

  2. Package ‘venn’↩︎