MATLAB 您所在的位置:网站首页 matlab怎么用点画图 MATLAB

MATLAB

2023-04-21 05:10| 来源: 网络整理| 查看: 265

整了个大活,写了一个能够生成非常精致三元相图的函数,这种图主要用于展示三种变量之间的比例,本期实验绘制效果如下:

编写不易,这个工具写的脑壳痛,求多多点赞,依旧先介绍咋使用,工具函数放在最后,同时提供gitee及fileexchange下载链接,若是日后代码更改会在这俩仓库同步更改。

教程部分1 三元相坐标区域创建

就一行代码就可以创建:

% 初始化三元相图(Init ternary plot) STA1=STernary();2 set 设置坐标区域最基本属性

set函数可以设置很多坐标区域属性,比如背景颜色Color:

% 背景色变为灰色(Set the background color to gray) set(STA1,'Color',[.9,.9,.9]);

比如设置ABC三个轴标签A_Label,B_Label,C_Label的文本:

% 设置标签文本(Set Label string) set(STA1,'A_Label','String','AAAAA') set(STA1,'B_Label','String','BBBBB') set(STA1,'C_Label','String','CCCCC')3 基本绘图

常见的 plot fill scatter contour contourf text 这些绘图函数都可以用,不过需要首字母大写并加个S,继续前面的代码往后写,画个散点图并增添图例:

% 绘制散点图(Draw scatter plot) A=rand(1,20); B=rand(1,20); C=rand(1,20); STA1.SScatter(A,B,C,40,'filled','CData',[0,0,0]); legend()4 set 设置其它属性

ABC各个轴、主刻度、次刻度、主网格、次网格、轴标签、刻度标签全部可以由set函数设置,这里仅举A相关的例子,BC轴就把A字母换换就好:

以下两种设置方式等价:

set(STA,'XXX','prop',.......)STA.set('XXX','prop',.......)% 设置A轴颜色和粗细(Set A_Axis's 'Color' and 'LineWidth') set(STA1,'A_Axis','Color',[0,0,.8],'LineWidth',3) % 设置A轴主网格颜色和粗细(Set A_Grid's 'Color' and 'LineWidth') set(STA1,'A_Grid','Color',[0,0,.8],'LineWidth',1.2) % 设置A轴次网格颜色线形 set(STA1,'A_MinorGrid','Color',[0,0,.8],'LineStyle','-.') % 设置A轴主刻度颜色 set(STA1,'A_Tick','Color',[0,0,.8]) % 设置A轴次刻度颜色 set(STA1,'A_MinorTick','Color',[0,0,.8]) % 设置A轴刻度标签字体和颜色 set(STA1,'A_TickLabel','Color',[0,0,.8],'FontSize',16) % 设置A轴标签字体和颜色及位置以及文本内容 set(STA1,'A_Label','Color',[0,0,.8],'FontSize',18,'Position',[.88,.6],'String',{'Ternary plot';'by Slandarer'})5 一些不常设置属性

重新构造一个坐标区域对象叭,不用之前那个灰灰的啦,首先是将标签移动到侧面:

STA2=STernary(); % 将标签移动到侧边(Move the label to the side) STA2.label2Side();

设置主次刻度长度,设置刻度值/网格值/刻度标签文本:

% 设置刻度长度(Set tick length) STA2.set('TickLenth',[.035,.02]) % 设置刻度值/网格值/刻度标签 % 'GridValues'/'TickValues' % 'MinorGridValues'/'MinorTickValues' % 'A_TickLabelStr'/'B_TickLabelStr'/'C_TickLabelStr' STA2.set('MinorGridValues',5:5:100) STA2.set('MinorTickValues',2.5:2.5:100) STA2.set('A_TickLabelStr',{'20%','40%','60%','80%','100%'})6 折线图基础绘图及绘图解读

折线图使用SPlot函数绘制:

% 初始化三元相图(Init ternary plot) STA=STernary(); % 绘制折线图及散点(Draw lines and scatter) STA.SPlot([2,2],[3,0],[5,8],'LineWidth',4,'Color',[.8,0,0]); STA.SPlot([2,7],[3,3],[5,0],'LineWidth',4,'Color',[0,.8,0]); STA.SPlot([2,0],[3,5],[5,5],'LineWidth',4,'Color',[0,0,.8]); STA.SScatter(2,3,5,180,'filled','CData',[1,1,1],'MarkerEdgeColor',[0,0,0],'LineWidth',2); % 绘制文本(Draw text) STA.SText(2+1,3,5,'(20%,30%,50%)','FontSize',16,'FontName','Cambria')

由图所示圆点比例为2:3:5那么平行于A轴网格的线会与A轴交在20%处,相应平行于B轴网格的线与B轴交在30%处。。。。。。同时实际上三条直线的长度也是呈2:3:5的比例的。

7 气泡图绘制

非常简单就几行代码:

% 初始化三元相图(Init ternary plot) STA=STernary(); % 随机构造数据(Randomly generated data) A=rand(1,50); B=rand(1,50); C=rand(1,50); sz=rand(1,50); % 绘制气泡图(Draw bubble chart) STA.SBubblechart(A,B,C,sz,'CData',A);

想改配色直接colormap即可:

colormap(bone)8 等高线图与填充等高线图

绘图第四个参数是网格划分点数,若是填[]即为默认值分为90段计算核密度,正常画等高线图会填满整个三角:

% 初始化三元相图(Init ternary plot) STA=STernary(); % 随机构造数据(Randomly generated data) A=rand(1,30); B=rand(1,30); C=rand(1,30); STA.SContourf(A,B,C,[],15,'LineWidth',1);

咋低于一定值不画呢,可以获取绘图的高度返回值Z,自定义要画等高线的高度:

% 获取核密度范围并等分(Obtain the range of ksdensity and divide it equally) [~,Z]=STA.SContourf(A,B,C,[],15,'Visible','off'); levels=linspace(.5,max(max(Z)),15); % 依据等值线绘制等高线及等高线填充(Draw contour and contourf by levels) CfHdl=STA.SContourf(A,B,C,[],levels,'LineWidth',1);

多个绘图绘制图例可以直接legend(),但这里我们有一个被隐藏的contourf,建议直接把想要画在图例上的图形句柄放在一个矩阵里:

legend([A,B,C],{'A','B','C'})% 获取核密度范围并等分(Obtain the range of ksdensity and divide it equally) [~,Z]=STA.SContourf(A,B,C,[],15,'Visible','off'); levels=linspace(.5,max(max(Z)),15); % 依据等值线绘制等高线及等高线填充(Draw contour and contourf by levels) CfHdl=STA.SContourf(A,B,C,[],levels,'LineWidth',1); CHdl=STA.SContour(A,B,C,[],levels,'LineWidth',1,'EdgeColor',[0,0,0]); SHdl=STA.SScatter(A,B,C,40,'filled','CData',[0,0,0]); % 绘制图例(Draw legend) legend([CfHdl,CHdl,SHdl],{'contourf','contour','scatter'},'FontSize',14,'FontName','Cambria')

改个颜色(这就是封面图):

colormap(turbo)9 变量范围及凸包

变量应该是非负的,建议自己先处理好数据,当然懒得写函数可以使用该工具自带的归一化工具:

ABC=STA.SNorm(ABC)

可以将每一列分别映射到0-1,每一列最小值映射到0,最大值映射到1.

ABC=STA.SNormByLim(ABC,[Amin,Amax,Bmin,Bmax,Cmin,Cmax])

该函数可以预先设置变量范围比如你的数据是0-50范围但是这组数据最大值就是45,那么SNorm函数会把45映射到1,但是SNormByLim函数就能把45映射到0.9。

变量范围映射并绘制散点图

% 初始化三元相图(Init ternary plot) STA=STernary(); % 随机构造数据(Randomly generated data) Pnt1=mvnrnd([10,30,10],[15 0 0;0 20 0;0 0 12],80); Pnt2=mvnrnd([30,10,15],[25 0 0;0 15 0;0 0 40],80); Pnt3=mvnrnd([25,10,35],[35 0 0;0 20 0;0 0 30],80); % 数据归一化(Normalization) Pnt1=STA.SNormByLim(Pnt1,[-5,50,-5,50,-5,50]); Pnt2=STA.SNormByLim(Pnt2,[-5,50,-5,50,-5,50]); Pnt3=STA.SNormByLim(Pnt3,[-5,50,-5,50,-5,50]); % 绘制散点图(Draw scatter) propCell={80,'filled','LineWidth',1,'MarkerEdgeColor',[1 1 1]*.3,'MarkerFaceColor'}; STA.SScatter(Pnt1(:,1),Pnt1(:,2),Pnt1(:,3),propCell{:},[0.4,0.76,0.65]); STA.SScatter(Pnt2(:,1),Pnt2(:,2),Pnt2(:,3),propCell{:},[1,0.55,0.38]); STA.SScatter(Pnt3(:,1),Pnt3(:,2),Pnt3(:,3),propCell{:},[0.55,0.63,0.8]);

凸包绘制本来想让大家用被注释掉的写法,想了想还是算了,注释掉的写法依旧能用,但我将其内置了:

% 已废弃写法(Obsolete method) % % 计算凸包(Get convhull) % [X1,Y1]=STA.ternData(Pnt1(:,1),Pnt1(:,2),Pnt1(:,3)); % [X2,Y2]=STA.ternData(Pnt2(:,1),Pnt2(:,2),Pnt2(:,3)); % [X3,Y3]=STA.ternData(Pnt3(:,1),Pnt3(:,2),Pnt3(:,3)); % [ind1,~]=convhull([X1,Y1]); % [ind2,~]=convhull([X2,Y2]); % [ind3,~]=convhull([X3,Y3]); % % % 绘制凸包(Draw convhull) % STA.SFill(Pnt1(ind1,1),Pnt1(ind1,2),Pnt1(ind1,3),[0.4,0.76,0.65],'FaceAlpha',.2,'LineWidth',2,'EdgeColor',[0.4,0.76,0.65]./2); % STA.SFill(Pnt2(ind2,1),Pnt2(ind2,2),Pnt2(ind2,3),[1,0.55,0.38],'FaceAlpha',.2,'LineWidth',2,'EdgeColor',[1,0.55,0.38]./2); % STA.SFill(Pnt3(ind3,1),Pnt3(ind3,2),Pnt3(ind3,3),[0.55,0.63,0.8],'FaceAlpha',.2,'LineWidth',2,'EdgeColor',[0.55,0.63,0.8]./2); % 绘制凸包(Draw convhull) STA.SConvhull(Pnt1(:,1),Pnt1(:,2),Pnt1(:,3),[0.4,0.76,0.65],'FaceAlpha',.2,'LineWidth',2,'EdgeColor',[0.4,0.76,0.65]./2); STA.SConvhull(Pnt2(:,1),Pnt2(:,2),Pnt2(:,3),[1,0.55,0.38],'FaceAlpha',.2,'LineWidth',2,'EdgeColor',[1,0.55,0.38]./2); STA.SConvhull(Pnt3(:,1),Pnt3(:,2),Pnt3(:,3),[0.55,0.63,0.8],'FaceAlpha',.2,'LineWidth',2,'EdgeColor',[0.55,0.63,0.8]./2); % 绘制图例(Draw legend) legend({'Data1','Data2','Data3','convex1','convex2','convex3'},'FontSize',14,'FontName','Cambria')10 利用nan同时绘制多条折线

没错我也考虑了减少循环的一些措施,工具函数支持适当加入nan将折线断开以同时绘制多条折线:

% 初始化三元相图(Init ternary plot) STA=STernary(); A=rand(1,20); B=rand(1,20); C=rand(1,20); A=[A;A*0+mean(A);A.*nan]; B=[B;B*0+mean(B);B.*nan]; C=[C;C*0+mean(C);C.*nan]; % 绘制折线图(Draw Line) STA.SScatter(A,B,C,40,'filled','CData',[0,0,0]); % 绘制散点图(Draw scatter plot) STA.SPlot(A(:),B(:),C(:),'LineWidth',1,'Color',[0,0,0]);工具函数完整代码classdef STernary >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> obj.BkgHdl=fill(obj.ax,[0,1,1/2],[0,0,sqrt(3)/2],[1,1,1],'EdgeColor','none'); obj.TriLHdl=fill(obj.ax,[0,1/2+1/40,0],[0,sqrt(3)/2+1/40*sqrt(3),sqrt(3)/2+1/40*sqrt(3)],[1,1,1],'EdgeColor','none'); obj.TriRHdl=fill(obj.ax,[1,1/2-1/40,1],[0,sqrt(3)/2+1/40*sqrt(3),sqrt(3)/2+1/40*sqrt(3)],[1,1,1],'EdgeColor','none'); obj.BkgHdl.Annotation.LegendInformation.IconDisplayStyle='off'; obj.TriLHdl.Annotation.LegendInformation.IconDisplayStyle='off'; obj.TriRHdl.Annotation.LegendInformation.IconDisplayStyle='off'; % Draw Minor Grid >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> obj.MinorGridValues=setdiff(obj.MinorGridValues,obj.GridValues); AMGX=[1-obj.MinorGridValues./200;obj.MinorGridValues./200;obj.MinorGridValues.*nan]; AMGY=[obj.MinorGridValues./200.*sqrt(3);obj.MinorGridValues./200.*sqrt(3);obj.MinorGridValues.*nan]; obj.A_MinorGrid=plot(obj.ax,AMGX(:),AMGY(:),'LineWidth',.5,'Color',[0,0,0,.2],'LineStyle','-'); obj.A_MinorGrid.Annotation.LegendInformation.IconDisplayStyle='off'; % BMGX=[1/2-obj.MinorGridValues./200;1-obj.MinorGridValues./100;obj.MinorGridValues.*nan]; BMGY=[sqrt(3)/2-obj.MinorGridValues./200.*sqrt(3);obj.MinorGridValues.*0;obj.MinorGridValues.*nan]; obj.B_MinorGrid=plot(obj.ax,BMGX(:),BMGY(:),'LineWidth',.5,'Color',[0,0,0,.2],'LineStyle','-'); obj.B_MinorGrid.Annotation.LegendInformation.IconDisplayStyle='off'; % CMGX=[obj.MinorGridValues./100;1/2+obj.MinorGridValues./200;obj.MinorGridValues.*nan]; CMGY=[obj.MinorGridValues.*0;1/2.*sqrt(3)-obj.MinorGridValues./200.*sqrt(3);obj.MinorGridValues.*nan]; obj.C_MinorGrid=plot(obj.ax,CMGX(:),CMGY(:),'LineWidth',.5,'Color',[0,0,0,.2],'LineStyle','-'); obj.C_MinorGrid.Annotation.LegendInformation.IconDisplayStyle='off'; % Draw Grid >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AGX=[1-obj.GridValues./200;obj.GridValues./200;obj.GridValues.*nan]; AGY=[obj.GridValues./200.*sqrt(3);obj.GridValues./200.*sqrt(3);obj.GridValues.*nan]; obj.A_Grid=plot(obj.ax,AGX(:),AGY(:),'LineWidth',.8,'Color',[0,0,0,.7],'LineStyle','-'); obj.A_Grid.Annotation.LegendInformation.IconDisplayStyle='off'; % BGX=[1/2-obj.GridValues./200;1-obj.GridValues./100;obj.GridValues.*nan]; BGY=[sqrt(3)/2-obj.GridValues./200.*sqrt(3);obj.GridValues.*0;obj.GridValues.*nan]; obj.B_Grid=plot(obj.ax,BGX(:),BGY(:),'LineWidth',.8,'Color',[0,0,0,.7],'LineStyle','-'); obj.B_Grid.Annotation.LegendInformation.IconDisplayStyle='off'; % CGX=[obj.GridValues./100;1/2+obj.GridValues./200;obj.GridValues.*nan]; CGY=[obj.GridValues.*0;1/2.*sqrt(3)-obj.GridValues./200.*sqrt(3);obj.GridValues.*nan]; obj.C_Grid=plot(obj.ax,CGX(:),CGY(:),'LineWidth',.8,'Color',[0,0,0,.7],'LineStyle','-'); obj.C_Grid.Annotation.LegendInformation.IconDisplayStyle='off'; % Draw Minor Tick >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> obj.MinorTickValues=setdiff(obj.MinorTickValues,obj.TickValues); AMTX=[1-obj.MinorTickValues./200;1-obj.MinorTickValues./200+cos(0).*obj.TickLenth(2);obj.MinorTickValues.*nan]; AMTY=[obj.MinorTickValues./200.*sqrt(3);obj.MinorTickValues./200.*sqrt(3)+sin(0).*obj.TickLenth(2);obj.MinorTickValues.*nan]; obj.A_MinorTick=plot(obj.ax,AMTX(:),AMTY(:),'LineWidth',.8,'Color',[0,0,0]); obj.A_MinorTick.Annotation.LegendInformation.IconDisplayStyle='off'; % BMTX=[1/2-obj.MinorTickValues./200;1/2-obj.MinorTickValues./200+cos(2*pi/3).*obj.TickLenth(2);obj.MinorTickValues.*nan];help STernary BMTY=[sqrt(3)/2-obj.MinorTickValues./200.*sqrt(3);sqrt(3)/2-obj.MinorTickValues./200.*sqrt(3)+sin(2*pi/3).*obj.TickLenth(2);obj.MinorTickValues.*nan]; obj.B_MinorTick=plot(obj.ax,BMTX(:),BMTY(:),'LineWidth',.8,'Color',[0,0,0]); obj.B_MinorTick.Annotation.LegendInformation.IconDisplayStyle='off'; % CMTX=[obj.MinorTickValues./100;obj.MinorTickValues./100+cos(-2*pi/3).*obj.TickLenth(2);obj.MinorTickValues.*nan]; CMTY=[obj.MinorTickValues.*0;obj.MinorTickValues.*0+sin(-2*pi/3).*obj.TickLenth(2);obj.MinorTickValues.*nan]; obj.C_MinorTick=plot(obj.ax,CMTX(:),CMTY(:),'LineWidth',.8,'Color',[0,0,0]); obj.C_MinorTick.Annotation.LegendInformation.IconDisplayStyle='off'; % Draw Tick >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ATX=[1-obj.TickValues./200;1-obj.TickValues./200+cos(0).*obj.TickLenth(1);obj.TickValues.*nan]; ATY=[obj.TickValues./200.*sqrt(3);obj.TickValues./200.*sqrt(3)+sin(0).*obj.TickLenth(1);obj.TickValues.*nan]; obj.A_Tick=plot(obj.ax,ATX(:),ATY(:),'LineWidth',1.2,'Color',[0,0,0]); obj.A_Tick.Annotation.LegendInformation.IconDisplayStyle='off'; % BTX=[1/2-obj.TickValues./200;1/2-obj.TickValues./200+cos(2*pi/3).*obj.TickLenth(1);obj.TickValues.*nan]; BTY=[sqrt(3)/2-obj.TickValues./200.*sqrt(3);sqrt(3)/2-obj.TickValues./200.*sqrt(3)+sin(2*pi/3).*obj.TickLenth(1);obj.TickValues.*nan]; obj.B_Tick=plot(obj.ax,BTX(:),BTY(:),'LineWidth',1.2,'Color',[0,0,0]); obj.B_Tick.Annotation.LegendInformation.IconDisplayStyle='off'; % CTX=[obj.TickValues./100;obj.TickValues./100+cos(-2*pi/3).*obj.TickLenth(1);obj.TickValues.*nan]; CTY=[obj.TickValues.*0;obj.TickValues.*0+sin(-2*pi/3).*obj.TickLenth(1);obj.TickValues.*nan]; obj.C_Tick=plot(obj.ax,CTX(:),CTY(:),'LineWidth',1.2,'Color',[0,0,0]); obj.C_Tick.Annotation.LegendInformation.IconDisplayStyle='off'; % Draw Axis >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> obj.A_Axis=plot(obj.ax,[1,1/2],[0,sqrt(3)/2],'Color',[0,0,0],'LineWidth',1.2); obj.B_Axis=plot(obj.ax,[1/2,0],[sqrt(3)/2,0],'Color',[0,0,0],'LineWidth',1.2); obj.C_Axis=plot(obj.ax,[0,1],[0,0],'Color',[0,0,0],'LineWidth',1.2); obj.A_Axis.Annotation.LegendInformation.IconDisplayStyle='off'; obj.B_Axis.Annotation.LegendInformation.IconDisplayStyle='off'; obj.C_Axis.Annotation.LegendInformation.IconDisplayStyle='off'; % Draw Tick Label >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for i=1:length(obj.TickValues) obj.A_TickLabel{i}=text(obj.ax,... 1-obj.TickValues(i)./200+cos(0).*(obj.TickLenth(1)+.01),... obj.TickValues(i)./200.*sqrt(3)+sin(0).*(obj.TickLenth(1)+.01),... obj.A_TickLabelStr{i},'FontName','Cambria','FontSize',12); obj.B_TickLabel{i}=text(obj.ax,... 1/2-obj.TickValues(i)./200+cos(2*pi/3).*(obj.TickLenth(1)+.01),... sqrt(3)/2-obj.TickValues(i)./200.*sqrt(3)+sin(2*pi/3).*(obj.TickLenth(1)+.01),... obj.B_TickLabelStr{i},'FontName','Cambria','FontSize',12,... 'Rotation',-60,'HorizontalAlignment','right'); obj.C_TickLabel{i}=text(obj.ax,... obj.TickValues(i)./100+cos(-2*pi/3).*(obj.TickLenth(1)+.01),... sin(-2*pi/3).*(obj.TickLenth(1)+.01),... obj.C_TickLabelStr{i},'FontName','Cambria','FontSize',12,... 'Rotation',60,'HorizontalAlignment','right'); end % Draw Label >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> obj.A_Label=text(obj.ax,1/2+cos(pi/2).*obj.LabelSep,sqrt(3)/2+sin(pi/2).*obj.LabelSep,'A-Axis',... 'FontName','Cambria','FontSize',16,'HorizontalAlignment','center','VerticalAlignment','bottom'); obj.B_Label=text(obj.ax,cos(-5*pi/6).*obj.LabelSep,sin(-5*pi/6).*obj.LabelSep,'B-Axis',... 'FontName','Cambria','FontSize',16,'HorizontalAlignment','right','VerticalAlignment','top'); obj.C_Label=text(obj.ax,1+cos(-pi/6).*obj.LabelSep,sin(-pi/6).*obj.LabelSep,'C-Axis',... 'FontName','Cambria','FontSize',16,'HorizontalAlignment','left','VerticalAlignment','top'); end % Copyright (c) 2023, Zhaoxu Liu / slandarer % ========================================================================= % @author : slandarer % gzh : slandarer随笔 % ------------------------------------------------------------------------- % Zhaoxu Liu / slandarer (2023). ternary % (https://www.mathworks.com/matlabcentral/fileexchange/127958-ternary), % MATLAB Central File Exchange. 检索来源 2023/4/18. % Set Ternary Axes ======================================================== % function setColor(obj,color) % set(obj.BkgHdl,'FaceColor',color); % end % ------------------------------------------------------------------------- function set(obj,hdlName,varargin) if isa(obj.(hdlName),'double')||(length(obj.(hdlName))>1&&(isa(obj.(hdlName){1},'char')||isa(obj.(hdlName){1},'string'))) switch true case isequal(hdlName,'Color') obj.Color=varargin{:}; set(obj.BkgHdl,'FaceColor',varargin{:}); case isequal(hdlName,'TickLenth') obj.TickLenth=varargin{:}; case isequal(hdlName(end-2:end),'ues') obj.(hdlName)=varargin{:}; case isequal(hdlName(end-2:end),'Str') obj.(hdlName)=varargin{:}; end % Renew Minor Grid >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> obj.MinorGridValues=setdiff(obj.MinorGridValues,obj.GridValues); AMGX=[1-obj.MinorGridValues./200;obj.MinorGridValues./200;obj.MinorGridValues.*nan]; AMGY=[obj.MinorGridValues./200.*sqrt(3);obj.MinorGridValues./200.*sqrt(3);obj.MinorGridValues.*nan]; set(obj.A_MinorGrid,'XData',AMGX(:),'YData',AMGY(:)); % BMGX=[1/2-obj.MinorGridValues./200;1-obj.MinorGridValues./100;obj.MinorGridValues.*nan]; BMGY=[sqrt(3)/2-obj.MinorGridValues./200.*sqrt(3);obj.MinorGridValues.*0;obj.MinorGridValues.*nan]; set(obj.B_MinorGrid,'XData',BMGX(:),'YData',BMGY(:)); % CMGX=[obj.MinorGridValues./100;1/2+obj.MinorGridValues./200;obj.MinorGridValues.*nan]; CMGY=[obj.MinorGridValues.*0;1/2.*sqrt(3)-obj.MinorGridValues./200.*sqrt(3);obj.MinorGridValues.*nan]; set(obj.C_MinorGrid,'XData',CMGX(:),'YData',CMGY(:)); % Renew Grid >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AGX=[1-obj.GridValues./200;obj.GridValues./200;obj.GridValues.*nan]; AGY=[obj.GridValues./200.*sqrt(3);obj.GridValues./200.*sqrt(3);obj.GridValues.*nan]; set(obj.A_Grid,'XData',AGX(:),'YData',AGY(:)); % BGX=[1/2-obj.GridValues./200;1-obj.GridValues./100;obj.GridValues.*nan]; BGY=[sqrt(3)/2-obj.GridValues./200.*sqrt(3);obj.GridValues.*0;obj.GridValues.*nan]; set(obj.B_Grid,'XData',BGX(:),'YData',BGY(:)); % CGX=[obj.GridValues./100;1/2+obj.GridValues./200;obj.GridValues.*nan]; CGY=[obj.GridValues.*0;1/2.*sqrt(3)-obj.GridValues./200.*sqrt(3);obj.GridValues.*nan]; set(obj.C_Grid,'XData',CGX(:),'YData',CGY(:)); % Renew Minor Tick >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> obj.MinorTickValues=setdiff(obj.MinorTickValues,obj.TickValues); AMTX=[1-obj.MinorTickValues./200;1-obj.MinorTickValues./200+cos(0).*obj.TickLenth(2);obj.MinorTickValues.*nan]; AMTY=[obj.MinorTickValues./200.*sqrt(3);obj.MinorTickValues./200.*sqrt(3)+sin(0).*obj.TickLenth(2);obj.MinorTickValues.*nan]; set(obj.A_MinorTick,'XData',AMTX(:),'YData',AMTY(:)); % BMTX=[1/2-obj.MinorTickValues./200;1/2-obj.MinorTickValues./200+cos(2*pi/3).*obj.TickLenth(2);obj.MinorTickValues.*nan]; BMTY=[sqrt(3)/2-obj.MinorTickValues./200.*sqrt(3);sqrt(3)/2-obj.MinorTickValues./200.*sqrt(3)+sin(2*pi/3).*obj.TickLenth(2);obj.MinorTickValues.*nan]; set(obj.B_MinorTick,'XData',BMTX(:),'YData',BMTY(:)); % CMTX=[obj.MinorTickValues./100;obj.MinorTickValues./100+cos(-2*pi/3).*obj.TickLenth(2);obj.MinorTickValues.*nan]; CMTY=[obj.MinorTickValues.*0;obj.MinorTickValues.*0+sin(-2*pi/3).*obj.TickLenth(2);obj.MinorTickValues.*nan]; set(obj.C_MinorTick,'XData',CMTX(:),'YData',CMTY(:)); % Renew Tick >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ATX=[1-obj.TickValues./200;1-obj.TickValues./200+cos(0).*obj.TickLenth(1);obj.TickValues.*nan]; ATY=[obj.TickValues./200.*sqrt(3);obj.TickValues./200.*sqrt(3)+sin(0).*obj.TickLenth(1);obj.TickValues.*nan]; set(obj.A_Tick,'XData',ATX(:),'YData',ATY(:)); % BTX=[1/2-obj.TickValues./200;1/2-obj.TickValues./200+cos(2*pi/3).*obj.TickLenth(1);obj.TickValues.*nan]; BTY=[sqrt(3)/2-obj.TickValues./200.*sqrt(3);sqrt(3)/2-obj.TickValues./200.*sqrt(3)+sin(2*pi/3).*obj.TickLenth(1);obj.TickValues.*nan]; set(obj.B_Tick,'XData',BTX(:),'YData',BTY(:)); % CTX=[obj.TickValues./100;obj.TickValues./100+cos(-2*pi/3).*obj.TickLenth(1);obj.TickValues.*nan]; CTY=[obj.TickValues.*0;obj.TickValues.*0+sin(-2*pi/3).*obj.TickLenth(1);obj.TickValues.*nan]; set(obj.C_Tick,'XData',CTX(:),'YData',CTY(:)); % Renew Tick Label >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> for i=1:length(obj.TickValues) set(obj.A_TickLabel{i},'Position',... [1-obj.TickValues(i)./200+cos(0).*(obj.TickLenth(1)+.01),... obj.TickValues(i)./200.*sqrt(3)+sin(0).*(obj.TickLenth(1)+.01)],... 'String',obj.A_TickLabelStr{mod(i-1,length(obj.TickValues))+1}); set(obj.B_TickLabel{i},'Position',... [1/2-obj.TickValues(i)./200+cos(2*pi/3).*(obj.TickLenth(1)+.01),... sqrt(3)/2-obj.TickValues(i)./200.*sqrt(3)+sin(2*pi/3).*(obj.TickLenth(1)+.01)],... 'String',obj.B_TickLabelStr{mod(i-1,length(obj.TickValues))+1}); set(obj.C_TickLabel{i},'Position',... [obj.TickValues(i)./100+cos(-2*pi/3).*(obj.TickLenth(1)+.01),... sin(-2*pi/3).*(obj.TickLenth(1)+.01)],... 'String',obj.C_TickLabelStr{mod(i-1,length(obj.TickValues))+1}); end else if length(obj.(hdlName))>1 tHdl=obj.(hdlName); for i=1:length(tHdl) set(tHdl{i},varargin{:}) end else set(obj.(hdlName),varargin{:}) end end end % ------------------------------------------------------------------------- function label2Side(obj) set(obj.A_Label,'Position',[3/4+cos(pi/6).*obj.LabelSep.*90,sqrt(3)/4+sin(pi/6).*obj.LabelSep.*90],... 'HorizontalAlignment','center','VerticalAlignment','bottom','Rotation',-60) set(obj.B_Label,'Position',[1/4+cos(5*pi/6).*obj.LabelSep.*90,sqrt(3)/4+sin(5*pi/6).*obj.LabelSep.*90],... 'HorizontalAlignment','center','VerticalAlignment','bottom','Rotation',60) set(obj.C_Label,'Position',[1/2+cos(-pi/2).*obj.LabelSep.*90,0+sin(-pi/2).*obj.LabelSep.*90],... 'HorizontalAlignment','center','VerticalAlignment','top','Rotation',0) end % Copyright (c) 2023, Zhaoxu Liu / slandarer % ========================================================================= % @author : slandarer % gzh : slandarer随笔 % ------------------------------------------------------------------------- % Zhaoxu Liu / slandarer (2023). ternary % (https://www.mathworks.com/matlabcentral/fileexchange/127958-ternary), % MATLAB Central File Exchange. 检索来源 2023/4/18. % Define Functions ======================================================== function scatterHdl=SScatter(obj,A,B,C,varargin) [X,Y]=obj.ternData(A,B,C); scatterHdl=scatter(obj.ax,X,Y,varargin{:}); end % ------------------------------------------------------------------------- function plotHdl=SPlot(obj,A,B,C,varargin) [X,Y]=obj.ternData(A,B,C); plotHdl=plot(obj.ax,X,Y,varargin{:}); end % ------------------------------------------------------------------------- function fillHdl=SFill(obj,A,B,C,varargin) [X,Y]=obj.ternData(A,B,C); fillHdl=fill(obj.ax,X,Y,varargin{:}); end % ------------------------------------------------------------------------- function convhullHdl=SConvhull(obj,A,B,C,varargin) [X,Y]=obj.ternData(A,B,C); [ind,~]=convhull([X,Y]); convhullHdl=fill(obj.ax,X(ind),Y(ind),varargin{:}); end % ------------------------------------------------------------------------- function textHdl=SText(obj,A,B,C,varargin) [X,Y]=obj.ternData(A,B,C); textHdl=text(obj.ax,X,Y,varargin{:}); end % ------------------------------------------------------------------------- function bubblechartHdl=SBubblechart(obj,A,B,C,varargin) [X,Y]=obj.ternData(A,B,C); bubblechartHdl=bubblechart(obj.ax,X,Y,varargin{:}); end % ------------------------------------------------------------------------- function [contourHdl,Z]=SContour(obj,A,B,C,N,varargin) if isempty(N),N=90;end [X,Y]=obj.ternData(A,B,C); [XX1,XX2]=meshgrid(linspace(0,1,N),linspace(0,1,N)); F=ksdensity([X,Y],[XX1(:),XX2(:)]); Z=reshape(F,size(XX1)); Z(XX2>XX1.*sqrt(3)+.03)=nan; Z(XX2>sqrt(3)-XX1.*sqrt(3)+.03)=nan; hdlSet=findobj(obj.ax,'Tag','TernaryContour'); if isempty(hdlSet) T=1; else T=1; for i=1:length(hdlSet) T=max(T,get(hdlSet(i),'UserData')+1); end end contour(obj.ax,XX1,XX2,Z,varargin{:},'Tag','TernaryContour','UserData',T); uistack(obj.TriLHdl,'top');uistack(obj.TriRHdl,'top') uistack(obj.A_MinorTick,'top');uistack(obj.B_MinorTick,'top');uistack(obj.C_MinorTick,'top'); uistack(obj.A_Tick,'top');uistack(obj.B_Tick,'top');uistack(obj.C_Tick,'top'); uistack(obj.A_Axis,'top');uistack(obj.B_Axis,'top');uistack(obj.C_Axis,'top'); for i=1:length(obj.A_TickLabel) uistack(obj.A_TickLabel{i},'top'); uistack(obj.B_TickLabel{i},'top'); uistack(obj.C_TickLabel{i},'top'); end uistack(obj.A_Label,'top');uistack(obj.B_Label,'top');uistack(obj.C_Label,'top'); contourHdl=findobj(obj.ax,'Tag','TernaryContour','UserData',T); end % ------------------------------------------------------------------------- function [contourfHdl,Z]=SContourf(obj,A,B,C,N,varargin) if isempty(N),N=90;end [X,Y]=obj.ternData(A,B,C); [XX1,XX2]=meshgrid(linspace(0,1,N),linspace(0,1,N)); F=ksdensity([X,Y],[XX1(:),XX2(:)]); Z=reshape(F,size(XX1)); Z(XX2>XX1.*sqrt(3)+.03)=nan; Z(XX2>sqrt(3)-XX1.*sqrt(3)+.03)=nan; hdlSet=findobj(obj.ax,'Tag','TernaryContour'); if isempty(hdlSet) T=1; else T=1; for i=1:length(hdlSet) T=max(T,get(hdlSet(i),'UserData')+1); end end contourf(obj.ax,XX1,XX2,Z,varargin{:},'Tag','TernaryContour','UserData',T); uistack(obj.TriLHdl,'top');uistack(obj.TriRHdl,'top') uistack(obj.A_MinorTick,'top');uistack(obj.B_MinorTick,'top');uistack(obj.C_MinorTick,'top'); uistack(obj.A_Tick,'top');uistack(obj.B_Tick,'top');uistack(obj.C_Tick,'top'); uistack(obj.A_Axis,'top');uistack(obj.B_Axis,'top');uistack(obj.C_Axis,'top'); for i=1:length(obj.A_TickLabel) uistack(obj.A_TickLabel{i},'top'); uistack(obj.B_TickLabel{i},'top'); uistack(obj.C_TickLabel{i},'top'); end uistack(obj.A_Label,'top');uistack(obj.B_Label,'top');uistack(obj.C_Label,'top'); contourfHdl=findobj(obj.ax,'Tag','TernaryContour','UserData',T); end % ------------------------------------------------------------------------- function [X,Y]=ternData(~,A,B,C) ABC=[A(:),B(:),C(:)]; ABC=ABC./sum(ABC,2); B=ABC(:,2);C=ABC(:,3); X=C+(1-C-B)./2; Y=0+sqrt(3).*(1-C-B)./2; end % ------------------------------------------------------------------------- function ABC=SNorm(~,ABC) ABC=ABC-min(ABC,[],1); ABC=ABC./max(ABC,[],1); end % ------------------------------------------------------------------------- function ABC=SNormByLim(~,ABC,Lim) ABC=ABC-Lim([1,3,5]); ABC=ABC./(Lim([2,4,6])-Lim([1,3,5])); end end % Copyright (c) 2023, Zhaoxu Liu / slandarer % ========================================================================= % @author : slandarer % gzh : slandarer随笔 % ------------------------------------------------------------------------- % Zhaoxu Liu / slandarer (2023). ternary % (https://www.mathworks.com/matlabcentral/fileexchange/127958-ternary), % MATLAB Central File Exchange. 检索来源 2023/4/18. end

本代码编写真的不易,光看工具函数也能看出工作量(写推文时mdnice都卡住了),希望大家该点赞的点赞,该在看的在看!!

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

Zhaoxu Liu / slandarer (2023). ternary (https://www.mathworks.com/matlabcentral/fileexchange/127958-ternary), MATLAB Central File Exchange. 检索来源 2023/4/18.

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

该工具可通过上述fileexchange链接获取,或者通过以下gitee仓库下载:



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有