韦恩图绘制的代码MATHWORKS上也有,不过最多只支持四组绘制,于是参考R语言ggVennDiagram
包制作了一款支持7组样本的韦恩图绘制MATLAB函数。
百度百科
文氏图(英语:Venn diagram),或译Venn图、温氏图、维恩图、范氏图,是在所谓的集合论(或者类的理论)数学分支中,在不太严格的意义下用以表示集合(或类)的一种草图。
注意:仅代码无法运行,需要导入.mat
格式的素材包,素材包及m
文件获取放在文末。
另:由于代码开发基于polyshape
对象,本韦恩图绘制函数理论上需要至少R2017b
及之后版本才能使用。
由于工具函数过长,将被放在最后展示,以下将先展示函数用法。
示例图
使用教程
1 数据格式
数值格式需要如下形式的数值向量,目前还不支持字符串元胞数组格式,请自行将其改编为数值向量,如下例子所示若数值400同时出现在X1及X2中,即说明该元素属于X1,X2的交集。
X1=randi([1,500],[100,1]);
X2=randi([1,500],[100,1]);
X3=randi([1,500],[100,1]);
X4=randi([1,500],[100,1]);
X5=randi([1,500],[100,1]);
X6=randi([1,500],[100,1]);
X7=randi([1,500],[100,1]);
2 基本使用
以下两种形式均可:
XX={X1,X2,X3,X4,X5,X6,X7};
VN=venn(XX{1:7});
VN=VN.draw();
VN=venn(X1,X2,X3,X4,X5,X6,X7);
VN=VN.draw();
3 添加标签
在draw
函数绘图前使用labels
函数添加标签:
VN=venn(X1,X2,X3,X4,X5,X6,X7);
VN=VN.labels('AAA','BBB','CCC','DDD','EEE','FFF','GGG');
VN=VN.draw();
4 样本数量
支持样本数量为2-7的任意值,例如绘制两样本则使用如下格式调用:
VN=venn(X1,X2);
VN=VN.draw();
以下展示2-7组样本绘制效果:
5 修改多边形格式
使用setPatch
批量修改多边形格式,Patch对象具有的格式均可以修改。
使用setPatchN
修改第N个多边形格式,Patch对象具有的格式均可以修改。
批量修改格式
全部改为灰黑色:
VN.setPatch('FaceColor',[0,0,0],'EdgeColor',[0,0,0])
修改第N个格式
单独将第1个对象改为灰黑色:
VN.setPatchN(1,'FaceColor',[0,0,0],'EdgeColor',[0,0,0])
循环修改格式
循环修改各个多边形颜色:
colorList=[78 101 155;
138 140 191;
184 168 207;
231 188 198;
253 207 158;
239 164 132;
182 118 108]./255;
for i=1:7
VN.setPatchN(i,'FaceColor',colorList(i,:),'EdgeColor',colorList(i,:))
end
6 字体修改
使用:
- setFont
- setLabel
分别修改数字和标签的格式,举个例子:
VN.setFont('Color',[.9,0,0],'FontSize',14)
VN.setLabel('Color',[0,0,.9],'FontSize',25,'FontName','Cambria')
完整代码
注意:仅代码无法运行,需要导入.mat
格式的素材包,素材包及m
文件获取放在文末。
classdef venn
% @author : slandarer
% 公众号 : slandarer随笔
% 知乎 : hikari
% 使用示例:
% =========================================================================
% X1=randi([1,500],[100,1]);
% X2=randi([1,500],[100,1]);
% X3=randi([1,500],[100,1]);
% X4=randi([1,500],[100,1]);
% X5=randi([1,500],[100,1]);
% X6=randi([1,500],[100,1]);
% X7=randi([1,500],[100,1]);
% XX={X1,X2,X3,X4,X5,X6,X7};
%
%
% VN=venn(XX{1:7});
% VN.draw();
properties
ax % 绘图坐标区域
% -----------------------------------------------------------------
linePnts
labelSet={' ',' ',' ',' ',' ',' ',' '};
% labels={'AAA','BBB','CCC','DDD','EEE','FFF','GGG'};
labelPos
% -----------------------------------------------------------------
classNum % 多边形数量
dataList % 数据列表
pshapeHdl % polyshape对象
fillHdl % fill绘制的半透明多边形
textHdl % 绘制文本的句柄
labelHdl % 绘制标签的句柄
end
methods
function obj = venn(varargin)
if isa(varargin{1},'matlab.graphics.axis.Axes')
obj.ax=varargin{1};varargin(1)=[];
else
obj.ax=gca;
end
hold on
obj.classNum=length(varargin);
obj.dataList=varargin;
% 获取mat文件中的线条数据
obj.linePnts=load('LD.mat');
obj.linePnts=obj.linePnts.lineData;
% 初始定义标签位置
obj.labelPos{2}=[-.38,.3;.38,.3];
obj.labelPos{3}=[-.38,.3;-.38,-.4;.38,-.4];
obj.labelPos{4}=[-.38,.2;.38,.2;-.15,.3;.15,.3];
obj.labelPos{5}=[cos(linspace(2*pi/5,2*pi,5)+2*pi/5-pi/7).*.47;
sin(linspace(2*pi/5,2*pi,5)+2*pi/5-pi/7).*.47]';
obj.labelPos{6}=[cos(linspace(2*pi/6,2*pi,6)+2*pi/3-pi/6).*.49;
sin(linspace(2*pi/6,2*pi,6)+2*pi/3-pi/6).*.49]';
obj.labelPos{6}=obj.labelPos{6}+[0,+.09;-.01,-.04;0,+.015;0,-.1;0,0;0,-.015];
obj.labelPos{7}=[cos(linspace(2*pi/7,2*pi,7)+2*pi/5-pi/7).*.47;
sin(linspace(2*pi/7,2*pi,7)+2*pi/5-pi/7).*.47]';
help venn
end
function obj=draw(obj)
warning off
% 坐标区域修饰
obj.ax.XLim=[-.5,.5];
obj.ax.YLim=[-.5,.5];
obj.ax.XTick=[];
obj.ax.YTick=[];
obj.ax.XColor='none';
obj.ax.YColor='none';
obj.ax.PlotBoxAspectRatio=[1,1,1];
% 循环绘制半透明多边形
tcolorList=lines(7);
for i=1:obj.classNum
tPData=obj.linePnts(obj.classNum).pnts{i};
obj.pshapeHdl{i}=polyshape(tPData(:,1),tPData(:,2));
obj.fillHdl(i)=fill(tPData(:,1),tPData(:,2),tcolorList(i,:),...
'FaceAlpha',.2,'LineWidth',1.5,'EdgeColor',tcolorList(i,:));
end
% 构造初始bool集合
baseData=[];
for i=1:obj.classNum
baseData=[baseData;obj.dataList{i}(:)];
end
baseShpae=polyshape([-.5,-.5,.5,.5],[.5,-.5,-.5,.5]);
pBool=abs(dec2bin((1:(2^obj.classNum-1))'))-48;
% 循环绘制标签
for i=1:obj.classNum
tPos=obj.labelPos{obj.classNum};
obj.labelHdl(i)=text(tPos(i,1),tPos(i,2),obj.labelSet{i},...
'HorizontalAlignment','center','FontName','Arial','FontSize',16);
end
% 循环计算数字位置
for i=1:size(pBool,1)
tShpae=baseShpae;
tData=baseData;
for j=1:size(pBool,2)
switch pBool(i,j)
case 1
tShpae=intersect(tShpae,obj.pshapeHdl{j});
tData=intersect(tData,obj.dataList{j});
case 0
tShpae=subtract(tShpae,obj.pshapeHdl{j});
tData=setdiff(tData,obj.dataList{j});
end
end
[cx,cy]=centroid(tShpae);
obj.textHdl(i)=text(cx,cy,num2str(length(tData)),...
'HorizontalAlignment','center','FontName','Arial');
end
end
% =================================================================
% 设置标签文本内容
function obj=labels(obj,varargin)
tlabel{length(varargin)}=' ';
for i=1:length(varargin)
tlabel{i}=varargin{i};
end
obj.labelSet=tlabel;
end
% 批量设置多边形格式
function setPatch(obj,varargin)
for i=1:obj.classNum
set(obj.fillHdl(i),varargin{:})
end
end
% 单独设置多边形格式
function setPatchN(obj,N,varargin)
for i=1:obj.classNum
set(obj.fillHdl(N),varargin{:})
end
end
% 设置数值字体
function setFont(obj,varargin)
for i=1:length(obj.textHdl)
set(obj.textHdl(i),varargin{:})
end
end
% 设置标签字体
function setLabel(obj,varargin)
for i=1:length(obj.labelHdl)
set(obj.labelHdl(i),varargin{:})
end
end
end
% @author : slandarer
% 公众号 : slandarer随笔
% 知乎 : hikari
end
转载说明
- file exchange链接:Zhaoxu Liu (2022). venn diagram 韦恩图 (https://www.mathworks.com/matlabcentral/fileexchange/116760-venn-diagram), MATLAB Central File Exchange. 检索来源 2022/8/26.
- 原文链接:微信公众号,MATLAB | 全网唯一!使用MATLAB绘制好看的韦恩图(venn)!
全部m文件及素材包获取,请扫描下方公众号并关注,后台回复:venn
或韦恩图
转载文章,原文出处:slandarer随笔,由古哥整理发布
如若转载,请注明出处:https://iymark.com/articles/2678.html