c/c++语言开发共享利用Matlab绘制好看的弦图

弦图在python中以及r中非常常见,但是matlab中却始终没有相关函数,file exchange中也没有工作做的较为完备的弦图绘制函数(不过现在有了,我已经往上面也传了一份hiahiahia)仅

弦图在python中以及r中非常常见,但是matlab中却始终没有相关函数,file exchange中也没有工作做的较为完备的弦图绘制函数(不过现在有了,我已经往上面也传了一份hiahiahia)

仅工具函数主体部分约300行,字符数约8000,能画出与r语言同等质量的弦图实属不易,希望能有个`点赞“!!!

由于工具函数过长,将被放在最后展示,以下将先展示函数用法

封面图

利用Matlab绘制好看的弦图

利用Matlab绘制好看的弦图

使用教程

1.数据格式

数据要求为全部数值大于等于0的数值矩阵,或者table数组,或者数值矩阵+行列名元胞数组,首先举个数值矩阵的例子:

数值矩阵

datamat=randi([0,5],[5,4]);     % 绘图  cc=chordchart(datamat);  cc=cc.draw();  

利用Matlab绘制好看的弦图

这样由于没对各个对象命名,因此会自动命名为rncn

数值矩阵+行列名元胞数组

这是最推荐的一种格式:

datamat=[2 0 1 2 5 1 2;           3 5 1 4 2 0 1;           4 0 5 5 2 4 3];  colname={'g1','g2','g3','g4','g5','g6','g7'};  rowname={'s1','s2','s3'};    cc=chordchart(datamat,'rowname',rowname,'colname',colname);  cc=cc.draw();  

利用Matlab绘制好看的弦图

rowname要和矩阵的行相同大小

colname要和矩阵的列相同大小

对于本列子来说第2行第3列数值是1,就说明有一份能量从s2流向g3,也就在这俩之间需要画单位宽度的弦。

table 数组

需要使用如下格式的table数组:

利用Matlab绘制好看的弦图

当然,如果各个行没有命名的话依旧会自动命名的。

2.修饰弦

弦的批量修饰

弦的批量修饰可以使用setchordprop函数,一切patch对象所具有的属性均可以被修饰,举个例子(修饰一下弦的颜色,边缘颜色,边缘线形状等):

cc.setchordprop('edgecolor',[.3,.3,.3],'linestyle','--',...      'linewidth',.1,'facecolor',[.3,.3,.3])  

利用Matlab绘制好看的弦图

弦的单独修饰

弦的单独修饰可以使用setchordmn函数,其中m,n值是和原始数值矩阵的行列完全对应的,举个例子(把s2流向g4的弦颜色更改为红色):

cc.setchordmn(2,4,'facecolor',[1,0,0])  

利用Matlab绘制好看的弦图

弦的颜色映射

使用setchordcolorbymap函数进行颜色映射,

matlab 自带的colormap均可用:

利用Matlab绘制好看的弦图

或者也可自行放入一个n×3大小的颜色列表,程序会自动对其进行插值:举个例子:

cc.setchordcolorbymap(copper(100))  

利用Matlab绘制好看的弦图

3.圆弧状方块修饰

圆弧状方块批量修饰

使用

setsquaret_prop

setsquaref_prop

分别修饰上方方块和下方方块,一切patch对象所具有的属性均可以被修饰,举个例子,上方方块批量修饰(改为黑色):

cc.setsquaret_prop('facecolor',[0,0,0])  

利用Matlab绘制好看的弦图

圆弧状方块单独修饰

使用

setsquaret_n

setsquaref_n

分别修饰上方方块和下方方块,举个例子,上方第二个方块单独修饰(改为红色):

cc.setsquaret_n(2,'facecolor',[.8,0,0])  

利用Matlab绘制好看的弦图

4.字体调整

使用setfont函数对字体进行调整,所有text对象具有的属性均可以修饰,举个例子(更改文本的字号、字体和颜色):

cc.setfont('fontsize',25,'fontname','cambria','color',[0,0,.8])  

利用Matlab绘制好看的弦图

5.显示和隐藏刻度

用法:

cc.tickstate('on')  % cc.tickstate('off')  

利用Matlab绘制好看的弦图

工具函数完整代码

classdef chordchart  % @author : slandarer  % gzh  : slandarer随笔    % 使用示例:  % =========================================================================  % datamat=[2 0 1 2 5 1 2;  %          3 5 1 4 2 0 1;  %          4 0 5 5 2 4 3];  % colname={'g1','g2','g3','g4','g5','g6','g7'};  % rowname={'s1','s2','s3'};  %   % cc=chordchart(datamat,'rowname',rowname,'colname',colname);  % cc=cc.draw()        properties          ax          arginlist={'colname','rowname'}          vermatlab   % matlab 版本: r2021a显示为2021,r2021b显示为2021.5          chordtable  % table数组          datamat     % 数值矩阵          colname={}; % 列名称          rowname={}; % 行名称          thetasetf          thetasett          % -----------------------------------------------------------          squarefhdl  % 绘制下方方块的图形对象矩阵          squarethdl  % 绘制下上方方块的图形对象矩阵          namefhdl    % 绘制下方文本的图形对象矩阵          namethdl    % 绘制上方文本的图形对象矩阵          chordmathdl % 绘制弦的图形对象矩阵          thetatickfhdl % 刻度句柄          thetatickthdl % 刻度句柄          rtickfhdl % 轴线句柄          rtickthdl % 轴线句柄      end        methods          function obj=chordchart(varargin)              if isa(varargin{1},'matlab.graphics.axis.axes')                  obj.ax=varargin{1};varargin(1)=[];              else                  obj.ax=gca;              end                            % 获取版本信息              tver=version('-release');              obj.vermatlab=str2double(tver(1:4))+(abs(tver(5))-abs('a'))/2;                if obj.vermatlab<2017                  hold on              else                  hold(obj.ax,'on')              end                              obj.datamat=varargin{1};varargin(1)=[];              if isa(obj.datamat,'table')              obj.chordtable=obj.datamat;                  if isempty(obj.chordtable.properties.rownames)                      for i=1:size(obj.chordtable.variables,1)                          obj.rowname{i}=['r',num2str(i)];                      end                  end              else                % 获取其他数据              for i=1:(length(varargin)-1)                  tid=ismember(obj.arginlist,varargin{i});                  if any(tid)                  obj.(obj.arginlist{tid})=varargin{i+1};                  end              end              tzerocell{1,size(obj.datamat,2)}=zeros(size(obj.datamat,1),1);              for i=1:size(obj.datamat,2)                  tzerocell{1,i}=zeros(size(obj.datamat,1),1);              end              if isempty(obj.colname)                  for i=1:size(obj.datamat,2)                      obj.colname{i}=['c',num2str(i)];                  end              end              if isempty(obj.rowname)                  for i=1:size(obj.datamat,1)                      obj.rowname{i}=['r',num2str(i)];                  end              end                              % 创建table数组              obj.chordtable=table(tzerocell{:});              obj.chordtable.variables=obj.datamat;              obj.chordtable.properties.variablenames=obj.colname;              obj.chordtable.properties.rownames=obj.rowname;                help chordchart              end          end            function obj=draw(obj)              obj.ax.xlim=[-1.38,1.38];              obj.ax.ylim=[-1.38,1.38];              obj.ax.xtick=[];              obj.ax.ytick=[];              obj.ax.xcolor='none';              obj.ax.ycolor='none';              obj.ax.plotboxaspectratio=[1,1,1];                % 计算绘图所用数值              tdmat=obj.chordtable.variables;              tdfrom=obj.chordtable.properties.rownames;              tdto=obj.chordtable.properties.variablenames;                tdmatuni=tdmat-min(min(tdmat));              tdmatuni=tdmatuni./max(max(tdmatuni));                sep1=1/20;              sep2=1/40;                ratiof=sum(tdmat,2)./sum(tdmat,[1,2]);              ratiof=[0,ratiof'];              ratiot=[0,sum(tdmat,1)./sum(tdmat,[1,2])];                sepnumf=size(tdmat,1);              sepnumt=size(tdmat,2);                seplen=pi*(1-2*sep1)*sep2;              baselenf=(pi*(1-sep2)-(sepnumf-1)*seplen);              baselent=(pi*(1-sep2)-(sepnumt-1)*seplen);              tcolor=[61 96 137;76 103 86]./255;              % 绘制下方方块              for i=1:sepnumf                  theta1=2*pi-pi*sep1/2-sum(ratiof(1:i))*baselenf-(i-1)*seplen;                  theta2=2*pi-pi*sep1/2-sum(ratiof(1:i+1))*baselenf-(i-1)*seplen;                  theta=linspace(theta1,theta2,100);                  x=cos(theta);y=sin(theta);                  obj.squarefhdl(i)=fill([1.05.*x,1.15.*x(end:-1:1)],[1.05.*y,1.15.*y(end:-1:1)],...                      tcolor(1,:),'edgecolor','none');                  theta3=(theta1+theta2)/2;                  obj.namefhdl(i)=text(cos(theta3).*1.28,sin(theta3).*1.28,tdfrom{i},'fontsize',12,'fontname','arial',...                      'horizontalalignment','center','rotation',-(1.5*pi-theta3)./pi.*180);                  obj.rtickfhdl(i)=plot(cos(theta).*1.17,sin(theta).*1.17,'color',[0,0,0],'linewidth',.8,'visible','off');              end              % 绘制上方放块              for j=1:sepnumt                  theta1=pi-pi*sep1/2-sum(ratiot(1:j))*baselent-(j-1)*seplen;                  theta2=pi-pi*sep1/2-sum(ratiot(1:j+1))*baselent-(j-1)*seplen;                  theta=linspace(theta1,theta2,100);                  x=cos(theta);y=sin(theta);                  obj.squarethdl(j)=fill([1.05.*x,1.15.*x(end:-1:1)],[1.05.*y,1.15.*y(end:-1:1)],...                      tcolor(2,:),'edgecolor','none');                  theta3=(theta1+theta2)/2;                  obj.namethdl(j)=text(cos(theta3).*1.28,sin(theta3).*1.28,tdto{j},'fontsize',12,'fontname','arial',...                      'horizontalalignment','center','rotation',-(.5*pi-theta3)./pi.*180);                  obj.rtickthdl(j)=plot(cos(theta).*1.17,sin(theta).*1.17,'color',[0,0,0],'linewidth',.8,'visible','off');              end                colorfunc=colorfuncfactory(flipud(summer(50)));              % 绘制弦                for i=1:sepnumf                  for j=sepnumt:-1:1                      theta1=2*pi-pi*sep1/2-sum(ratiof(1:i))*baselenf-(i-1)*seplen;                      theta2=2*pi-pi*sep1/2-sum(ratiof(1:i+1))*baselenf-(i-1)*seplen;                      theta3=pi-pi*sep1/2-sum(ratiot(1:j))*baselent-(j-1)*seplen;                      theta4=pi-pi*sep1/2-sum(ratiot(1:j+1))*baselent-(j-1)*seplen;                        trowv=tdmat(i,:);trowv=[0,trowv(end:-1:1)./sum(trowv)];                      tcolv=tdmat(:,j)';tcolv=[0,tcolv./sum(tcolv)];                               % 贝塞尔曲线断点计算                      theta5=(theta2-theta1).*sum(trowv(1:(sepnumt+1-j)))+theta1;                      theta6=(theta2-theta1).*sum(trowv(1:(sepnumt+2-j)))+theta1;                      theta7=(theta3-theta4).*sum(tcolv(1:i))+theta4;                      theta8=(theta3-theta4).*sum(tcolv(1:i+1))+theta4;                      tpnt1=[cos(theta5),sin(theta5)];                      tpnt2=[cos(theta6),sin(theta6)];                      tpnt3=[cos(theta7),sin(theta7)];                      tpnt4=[cos(theta8),sin(theta8)];                        if j==sepnumt,obj.thetasetf(i,1)=theta5;end                      obj.thetasetf(i,j+1)=theta6;                      if i==1,obj.thetasett(1,j)=theta7;end                      obj.thetasett(i+1,j)=theta8;                        % 计算曲线                      tline1=beziercurve([tpnt1;0,0;tpnt3],200);                      tline2=beziercurve([tpnt2;0,0;tpnt4],200);                      tline3=[cos(linspace(theta6,theta5,100))',sin(linspace(theta6,theta5,100))'];                      tline4=[cos(linspace(theta7,theta8,100))',sin(linspace(theta7,theta8,100))'];                      obj.chordmathdl(i,j)=fill([tline1(:,1);tline4(:,1);tline2(end:-1:1,1);tline3(:,1)],...                           [tline1(:,2);tline4(:,2);tline2(end:-1:1,2);tline3(:,2)],...                           colorfunc(tdmatuni(i,j)),'facealpha',.3,'edgecolor','none');                      if tdmat(i,j)==0                          set(obj.chordmathdl(i,j),'visible','off')                      end                       end                    % 绘制刻度线                  tx=[cos(obj.thetasetf(i,:)).*1.17;cos(obj.thetasetf(i,:)).*1.19;nan.*ones(1,sepnumt+1)];                  ty=[sin(obj.thetasetf(i,:)).*1.17;sin(obj.thetasetf(i,:)).*1.19;nan.*ones(1,sepnumt+1)];                  obj.thetatickfhdl(i)=plot(tx(:),ty(:),'color',[0,0,0],'linewidth',.8,'visible','off');              end              for j=1:sepnumt                  tx=[cos(obj.thetasett(:,j)').*1.17;cos(obj.thetasett(:,j)').*1.19;nan.*ones(1,sepnumf+1)];                  ty=[sin(obj.thetasett(:,j)').*1.17;sin(obj.thetasett(:,j)').*1.19;nan.*ones(1,sepnumf+1)];                  obj.thetatickthdl(j)=plot(tx(:),ty(:),'color',[0,0,0],'linewidth',.8,'visible','off');              end                  % 贝塞尔函数              function pnts=beziercurve(pnts,n)                  t=linspace(0,1,n);                  p=size(pnts,1)-1;                  coe1=factorial(p)./factorial(0:p)./factorial(p:-1:0);                  coe2=((t).^((0:p)')).*((1-t).^((p:-1:0)'));                  pnts=(pnts'*(coe1'.*coe2))';              end                % 渐变色句柄生成函数              function colorfunc=colorfuncfactory(colorlist)                  x=(0:size(colorlist,1)-1)./(size(colorlist,1)-1);                  y1=colorlist(:,1);y2=colorlist(:,2);y3=colorlist(:,3);                  colorfunc=@(x)[interp1(x,y1,x,'linear')',interp1(x,y2,x,'linear')',interp1(x,y3,x,'linear')'];              end          end          % =================================================================          % 批量弦属性设置          function setchordprop(obj,varargin)              tdmat=obj.chordtable.variables;              for i=1:size(tdmat,1)                  for j=1:size(tdmat,2)                      set(obj.chordmathdl(i,j),varargin{:});                  end              end          end          % 单独弦属性设置          function setchordmn(obj,m,n,varargin)              set(obj.chordmathdl(m,n),varargin{:});          end          % 根据colormap映射颜色          function setchordcolorbymap(obj,colorlist)              tdmat=obj.chordtable.variables;              tdmatuni=tdmat-min(min(tdmat));              tdmatuni=tdmatuni./max(max(tdmatuni));                colorfunc=colorfuncfactory(colorlist);              for i=1:size(tdmat,1)                  for j=1:size(tdmat,2)                      set(obj.chordmathdl(i,j),'facecolor',colorfunc(tdmatuni(i,j)));                  end              end              % 渐变色句柄生成函数              function colorfunc=colorfuncfactory(colorlist)                  x=(0:size(colorlist,1)-1)./(size(colorlist,1)-1);                  y1=colorlist(:,1);y2=colorlist(:,2);y3=colorlist(:,3);                  colorfunc=@(x)[interp1(x,y1,x,'linear')',interp1(x,y2,x,'linear')',interp1(x,y3,x,'linear')'];              end          end              % -----------------------------------------------------------------          % 批量上方方块属性设置          function setsquaret_prop(obj,varargin)              tdmat=obj.chordtable.variables;              for j=1:size(tdmat,2)                  set(obj.squarethdl(j),varargin{:});              end          end          % 单独上方方块属性设置          function setsquaret_n(obj,n,varargin)              set(obj.squarethdl(n),varargin{:});          end          % 批量下方方块属性设置          function setsquaref_prop(obj,varargin)              tdmat=obj.chordtable.variables;              for i=1:size(tdmat,1)                  set(obj.squarefhdl(i),varargin{:});              end          end          % 单独上方方块属性设置          function setsquaref_n(obj,n,varargin)              set(obj.squarefhdl(n),varargin{:});          end              % -----------------------------------------------------------------          % 字体设置          function setfont(obj,varargin)              tdmat=obj.chordtable.variables;              for i=1:size(tdmat,1)                  set(obj.namefhdl(i),varargin{:});              end              for j=1:size(tdmat,2)                  set(obj.namethdl(j),varargin{:});              end           end              % -----------------------------------------------------------------          % 刻度开关          function tickstate(obj,state)              tdmat=obj.chordtable.variables;              for i=1:size(tdmat,1)                  set(obj.thetatickfhdl(i),'visible',state);                  set(obj.rtickfhdl(i),'visible',state);              end              for j=1:size(tdmat,2)                  set(obj.thetatickthdl(j),'visible',state);                  set(obj.rtickthdl(j),'visible',state);              end                    end      end  end  

封面图绘制代码

封面一

% demo 1  % @author : slandarer  % gzh  : slandarer随笔    datamat=[2 0 1 2 5 1 2;           3 5 1 4 2 0 1;           4 0 5 5 2 4 3];  colname={'g1','g2','g3','g4','g5','g6','g7'};  rowname={'s1','s2','s3'};    cc=chordchart(datamat,'rowname',rowname,'colname',colname);  cc=cc.draw();    cc.setfont('fontsize',17,'fontname','cambria')  cc.tickstate('on')  

利用Matlab绘制好看的弦图

封面二

% demo 2  % @author : slandarer  % gzh : slandarer随笔    datamat=[2 0 1 2 5 1 2;           3 5 1 4 2 0 1;           4 0 5 5 2 4 3];  colname={'g1','g2','g3','g4','g5','g6','g7'};  rowname={'s1','s2','s3'};    cc=chordchart(datamat,'rowname',rowname,'colname',colname);  cc=cc.draw();    % 弦属性设置 ===============================================================  % cc.setchordprop('edgecolor',[.3,.3,.3],'linestyle','--',...  %     'linewidth',.1,'facecolor',[.3,.3,.3])    % cc.setchordmn(2,4,'facecolor',[1,0,0])    cc.setchordcolorbymap(copper(100))      % 方块属性设置 =============================================================  cc.setsquaret_prop('facecolor',[0,0,0])  cc.setsquaret_n(2,'facecolor',[.8,0,0])  % cc.setsquaref_prop('facecolor',[0,0,0])  % cc.setsquaref_n(2,'facecolor',[.8,0,0])    % 字体设置 =================================================================  cc.setfont('fontsize',17,'fontname','cambria','color',[0,0,.8])      % 刻度开关设置 =============================================================  cc.tickstate('on')  

利用Matlab绘制好看的弦图

以上就是利用matlab绘制好看的弦图的详细内容,更多关于matlab弦图的资料请关注<计算机技术网(www.ctvol.com)!!>其它相关文章!

需要了解更多c/c++开发分享利用Matlab绘制好看的弦图,都可以关注C/C++技术分享栏目—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/1237003.html

(0)
上一篇 2022年9月7日
下一篇 2022年9月7日

精彩推荐