MATLAB | 全网唯一,使用MATLAB绘制精致的环形树状图

Posted slandarer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MATLAB | 全网唯一,使用MATLAB绘制精致的环形树状图相关的知识,希望对你有一定的参考价值。

绘制效果

请叫我平平无奇的绘图天才,这期一次性带来俩工具函数,分别是两层和三层的环形树状图,可以用来展示数据分类和层级:

理顺层级关系属实理得头秃,代码编写不易点个叭!!

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


双层环形树状图

基本使用

处理的数据对象是两列的元胞数组,数组内容物为字符串,像下面这样:

treeList='竞赛','数学竞赛';'竞赛','英语竞赛';'竞赛','美赛';'竞赛','数模国赛';'竞赛','网络挑战赛';'竞赛','英语翻译';
    '编程','python';'编程','MATLAB';'编程','C#';'编程','C++';'编程','C';'编程','java';'编程','js';'编程','R';'编程','html';
    '编程','php';'编程','rust';'编程','julia';'编程','perl';'编程','carbon';'编程','lisp';
    '技能','office';'技能','LaTeX';'技能','PS';'技能','PR';'技能','excel';'技能','视频剪辑';'技能','bat';
    '基础知识','代数集合';'基础知识','傅里叶';'基础知识','抽代';'基础知识','数分';'基础知识','高代';'基础知识','解几';
    '基础知识','实变';'基础知识','复变';'基础知识','运筹学';'基础知识','泛函';'基础知识','张量分解';'基础知识','概率论';
    '开发工具','eclipse';'开发工具','git';'开发工具','svn';'开发工具','gitee';'开发工具','jupyter';'开发工具','macos';
    '开发工具','postman';'开发工具','vscode';'开发工具','mdnice';'开发工具','pycharm';'开发工具','vim';'开发工具','svn';
    '爱好','国画';'爱好','乒乓球';'爱好','折纸';'爱好','雕刻';'爱好','篮球';'爱好','足球'
    '爱好','唱';'爱好','跳';'爱好','rap';'爱好','背带裤制作';'爱好','理发';

CT=circleTree2(treeList);
CT=CT.draw();

好,画完结束了,当然线更多会比较好看,这里自己构造一些ABCD类再画个图:

treeList=[],[];
k=1;
classNameSet='A','B','C','D','E','F';
classNumSet=[20,20,20,25,30,35];
for i=1:6
    for j=1:classNumSet(i)
        treeListk,1=['CLASS ',classNameSeti];
        treeListk,2=[classNameSeti,num2str(j)];
        k=k+1;
    end
end

CT=circleTree2(treeList);
CT=CT.draw();

修改配色

使用setColorN设置各个类的颜色,比如将第2个类设为红色:

CT.setColorN(2,[.8,0,0]);

循环全部设置为灰色:

for i=1:6
    CT.setColorN(i,[.8,.8,.8]);
end

修改字体

使用setLable1setLable1修改两层文本字体,例如:

CT.setLable1('FontSize',16,'Color',[0,0,.8]);
CT.setLable2('FontSize',13,'Color',[0,.6,.8]);


三层环形树状图

基本使用

与上面双层环形树状图绘制方式一模一样,三层的不太好构造,这里直接从excel读取数据绘制,数据为往年诺贝尔奖获得者及其奖项、国籍

读取数据并绘制三层环形树状图:

treeList=readcell('data.xlsx');
treeList=treeList(:,1:3);

CT=circleTree3(treeList);
CT=CT.draw();

其他属性设置方式与之前的双层绘制函数完全相同,由于怕文字互相遮挡,故只展示占比大于5%的类,想要隐藏或显示全部类,可以设置文本的Visible属性为on/off

CT.setLable2('Visible','on');

虽然有点乱,但是可以缩放查看细节:


完整代码

大量代码,前方高能!!

双层

classdef circleTree2
% @author : slandarer
% gzh  : slandarer随笔 

    properties
        ax,treeList
        ClassLine,ChildLine
        ClassScatter,MeanScatter
        LabelHdl0,LabelHdl1
    end

    methods
        function obj=circleTree2(treeList)
            obj.ax=gca;hold on;
            obj.treeList=treeList;         
        end

        function obj=draw(obj)
            % 坐标区域属性设置 ==============================================
            obj.ax=gca;hold on
            obj.ax.XLim=[-1,1];
            obj.ax.YLim=[-1,1];
            obj.ax.XTick=[];
            obj.ax.YTick=[];
            obj.ax.XColor='none';
            obj.ax.YColor='none';
            obj.ax.PlotBoxAspectRatio=[1,1,1];

            fig=obj.ax.Parent;
            if max(fig.Position(3:4))<600
                fig.Position(3:4)=1.8.*fig.Position(3:4);
                fig.Position(1:2)=fig.Position(1:2)./3;
            end
            % ax.LooseInset=[0,0,0,0];
            % 理顺层级 =====================================================
            classNameList=unique(obj.treeList(:,1));
            childrenListlength(classNameList)=[];
            classSize(length(classNameList))=0;
            for i=1:length(classNameList)
                childrenListi=find(strcmp(classNameListi,obj.treeList(:,1)));
                classSize(i)=length(childrenListi);
            end
            % 开始绘图 =====================================================
            sepTheta=2/30/length(classSize);
            cumTheta=[0,28/30*cumsum(classSize)./sum(classSize)];
            colorList=[127,91,93;187,128,110;197,173,143;59,71,111;104,95,126;76,103,86;112,112,124;
                72,39,24;197,119,106;160,126,88;238,208,146]./255;
            colorList=[colorList;rand(length(classSize),3)];
            colorList=colorList(4:end,:);
            for i=1:length(classSize)
                thetaList=linspace(sepTheta*i+cumTheta(i),sepTheta*i+cumTheta(i+1),classSize(i)).*2.*pi;
                bX1=[];bY1=[];
                for j=1:classSize(i)
                    oX1=[cos(thetaList(j)),cos(thetaList(j)).*0.9,cos(mean(thetaList)).*0.7,cos(mean(thetaList)).*0.45];
                    oY1=[sin(thetaList(j)),sin(thetaList(j)).*0.9,sin(mean(thetaList)).*0.7,sin(mean(thetaList)).*0.45];
                    bXY1=bezierCurve([oX1',oY1'],200);
                    bX1=[bX1;bXY1(:,1);nan];
                    bY1=[bY1;bXY1(:,2);nan];
                    nameList1=obj.treeList(:,2);
                    nameList1=nameList1(childrenListi);
                    rotation=thetaList(j)/pi*180;
                    if rotation>90&&rotation<270
                        rotation=rotation+180;
                        obj.LabelHdl1(i,j)=text(cos(thetaList(j)).*1.03,sin(thetaList(j)).*1.03,nameList1j,'Rotation',rotation,'HorizontalAlignment','right');
                    else
                        obj.LabelHdl1(i,j)=text(cos(thetaList(j)).*1.03,sin(thetaList(j)).*1.03,nameList1j,'Rotation',rotation);
                    end
                    
                end
                meanTheta=mean(thetaList);
                obj.ChildLine(i)=plot(bX1,bY1,'Color',[colorList(i,:),.4],'LineWidth',1.5);
                oX0=[cos(meanTheta).*0.46,cos(meanTheta).*0.44,0.05,0];
                oY0=[sin(meanTheta).*0.46,sin(meanTheta).*0.44,-0.15,0];
                bXY0=bezierCurve([oX0',oY0'],200);
                obj.ClassLine(i)=plot(bXY0(:,1),bXY0(:,2),'Color',[colorList(i,:),.8],'LineWidth',1.5);
                obj.ClassScatter(i)=scatter(cos(meanTheta).*0.45,sin(meanTheta).*0.45,'filled',...
                    'CData',colorList(i,:),'MarkerEdgeColor',[.4,.4,.4],'SizeData',60);
                rotation=meanTheta/pi*180;
                if rotation>90&&rotation<270
                    rotation=rotation+180;
                    obj.LabelHdl0(i)=text(cos(meanTheta).*0.48,sin(meanTheta).*0.48,classNameListi,...
                        'Rotation',rotation,'HorizontalAlignment','right','FontSize',12,'VerticalAlignment','cap');
                else
                    obj.LabelHdl0(i)=text(cos(meanTheta).*0.48,sin(meanTheta).*0.48,classNameListi,...
                        'Rotation',rotation,'FontSize',12,'VerticalAlignment','cap');
                end
            end
            obj.MeanScatter=scatter(0,0,'filled','CData',mean(colorList(1:length(classSize),:)),'MarkerEdgeColor',[.4,.4,.4],'MATLAB | 全网唯一,使用MATLAB绘制好看的韦恩图(venn)

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

MATLAB | 全网唯一,使用MATLAB绘制精致的环形树状图

MATLAB | 全网唯一,使用MATLAB绘制精致的环形树状图

MATLAB | 全网唯一 ,MATLAB绘制阴影柱状图(填充斜线)

MATLAB | 全网唯一 ,MATLAB绘制阴影柱状图(填充斜线)