当前位置: 首页 > news >正文

MATLAB | 全网唯一,使用MATLAB绘制好看的韦恩图(venn)

韦恩图绘制的代码MATHWORKS上也有,不过最多只支持四组绘制,于是我参考R语言ggVennDiagram包制作了一款支持7组样本的韦恩图绘制MATLAB函数。

注意:仅代码无法运行,需要导入.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随笔

% 使用示例:
% =========================================================================
% 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随笔
end

MATLAB韦恩图绘制能画成这样属实不易,如果有用请留个叭~

未经允许本代码请勿作商业用途,引用的话可以引用我file exchange上的链接,可使用如下格式:

Zhaoxu Liu (2022). venn diagram 韦恩图 (https://www.mathworks.com/matlabcentral/fileexchange/116760-venn-diagram), MATLAB Central File Exchange. 检索来源 2022/8/26.

若转载请保留以上file exchange链接及本文链接!!!

全部m文件及素材包获取:
链接:https://pan.baidu.com/s/1w1YfaXN6d5j0Ras60MVQ2Q?pwd=slan
提取码:slan

相关文章:

  • 2D Transpose算子GPU实现和优化
  • 软件复杂性的来源与应对
  • 11.9 表达式求值
  • 09-排序3 Insertion or Heap Sort(浙大数据结构)
  • java-python+vue社区防疫服务管理系统网站
  • sparksql insertinto 源码解析
  • 反射之获取Class
  • 【博客477】prometheus-----数值数据编码(varint与zigzag)
  • LCMXO2-2000HC-4FTG256C FPGA MachXO2系列 256-FTBGA 现场可编程门阵列
  • 初始Cpp之 四、数据类型
  • office2019如何自定义安装位置?
  • java基于ssm的汽车维修保养管理系统
  • Std::optional 源码分析
  • 目标检测——关键点检测学习记录(四):人脸和手部特征点检测
  • IMX6ULL学习笔记(5)——获取和编译U-Boot
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • iOS小技巧之UIImagePickerController实现头像选择
  • jquery ajax学习笔记
  • NLPIR语义挖掘平台推动行业大数据应用服务
  • Node项目之评分系统(二)- 数据库设计
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • python学习笔记-类对象的信息
  • React-生命周期杂记
  • spring cloud gateway 源码解析(4)跨域问题处理
  • Vue2.0 实现互斥
  • windows下mongoDB的环境配置
  • 说说动画卡顿的解决方案
  • 算法系列——算法入门之递归分而治之思想的实现
  • 我有几个粽子,和一个故事
  • 线性表及其算法(java实现)
  • 一个SAP顾问在美国的这些年
  • 与 ConTeXt MkIV 官方文档的接驳
  • zabbix3.2监控linux磁盘IO
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • 如何正确理解,内页权重高于首页?
  • !!java web学习笔记(一到五)
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (Bean工厂的后处理器入门)学习Spring的第七天
  • (分享)自己整理的一些简单awk实用语句
  • (新)网络工程师考点串讲与真题详解
  • (一)UDP基本编程步骤
  • (转)Unity3DUnity3D在android下调试
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .NET实现之(自动更新)
  • .NET文档生成工具ADB使用图文教程
  • .net中生成excel后调整宽度
  • @JSONField或@JsonProperty注解使用
  • @WebService和@WebMethod注解的用法
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • [ C++ ] 继承
  • [ 常用工具篇 ] AntSword 蚁剑安装及使用详解
  • [ai笔记9] openAI Sora技术文档引用文献汇总
  • [Android]使用Android打包Unity工程
  • [Android学习笔记]ScrollView的使用