MATLAB | 两种上色方式的旭日图绘制

2023-10-25 11:12

本文主要是介绍MATLAB | 两种上色方式的旭日图绘制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

嘿,这次真的是好久不见了,好不容易才有点空写点文章,这段时间忙到后台回复都有点来不及看,很抱歉有一部分后台留言刚看到就已经超过时限没法回复了,不过根据大家的留言,需求主要集中在希望出一期旭日图的教程,今天它来啦~

旭日图要说简单也不简单,要说难也不算难,唯一难点估计就是将数据分类排好序,然后每一圈能对应起来呗,上色啥的也不算啥难点,因此这期就简单教大家如何把大框架画出来以及提供两种上色方式。

还是挺酷的,近期没啥空单独开发出一个支持更多上色模式的类,大家可以先根据本文提供的代码先自行DIY着。


教程部分

0 数据

这里懒得搜集数据,自己随机生成了一个table类型数据,前三列都是名称,最后一列是数值:

rng(1)
ULList = 'ABCD';
LLList = 'abcd';rowNum = 50;
idx1   = randi([1,length(ULList)],[1,rowNum]);
idx2   = randi([1,3],[rowNum,1]);
Name1  = ULList(idx1'*ones(1,4));
Name2  = [LLList(idx1'*ones(1,4)),num2str(idx2)];
Name3  = [LLList(idx1)',num2str(idx2),...char(45.*ones(rowNum,1)),char(randi([97,122],[rowNum,5]))];
Value  = rand([rowNum,1]);
Table  = table(Name1,Name2,Name3,Value);

大概长这样:


1 数据处理

利用 grp2idx 进行分类,利用 sortrows 将相同类归在一起

% 利用 grp2idx 进行分类,利用 sortrows 将相同类归在一起
NameList  = Table.Properties.VariableNames;
NameNum   = length(NameList)-1;
NameCell{NameNum} = ' ';
valueList = zeros(length(Table.(NameList{1})),NameNum);
for i = 1:NameNum-1tName = Table.(NameList{i});tUniq = unique(tName,'rows');NameCell{i} = tUniq;ind = grp2idx([tUniq;tName]);ind(1:length(tUniq)) = [];valueList(:,i) = ind;
end
valueList(:,end) = -Table.(NameList{end});
[VAL,IDX] = sortrows(valueList,1:size(valueList,2));
VAL(:,end) = -VAL(:,end);

2 属性预设

设置配色,字体,文本显示的阈值等信息:

% 此处可以设置配色
CList=[0.3882    0.5333    0.70591.0000    0.6824    0.20390.9373    0.4353    0.41570.5490    0.7608    0.79220.3333    0.6784    0.53730.7647    0.7373    0.24710.7333    0.4627    0.57650.7294    0.6275    0.58040.6627    0.7098    0.68240.4627    0.4627    0.4627];
% 在这可修改字体
FontProp = {'FontSize',12,'Color',[0,0,0]};
% 在这可设置比例低于多少的部分不显示文字
TextThreshold = 0.012;

3 绘图

径向渐变

% 开始绘图
figure('Units','normalized','Position',[.2,.1,.52,.72]);
ax = gca; hold on
ax.DataAspectRatio = [1,1,1];
ax.XColor = 'none';
ax.YColor = 'none';
tT = linspace(0,1,100);
for i = 1:size(VAL,2)-1tRateSum = 0;tNum = length(NameCell{i});for j = 1:tNumtRate = sum(VAL(VAL(:,i) == j,end))./sum(VAL(:,end));  tTheta = [tRateSum+tT.*tRate,tRateSum+tRate-tT.*tRate].*pi.*2;tR = [tT.*0+i,tT.*0+i+1];if i == 1fill(cos(tTheta).*tR,sin(tTheta).*tR,CList(j,:),'EdgeColor',[1,1,1],'LineWidth',1)elsetCN = VAL(find(VAL(:,i) == j,1),1);fill(cos(tTheta).*tR,sin(tTheta).*tR,...CList(tCN,:).*0.8^(i-1)+[1,1,1].*(1-0.8^(i-1)),'EdgeColor',[1,1,1],'LineWidth',1)endrotation = (tRateSum+tRate/2)*360;if tRate > TextThresholdif rotation>90&&rotation<270rotation=rotation+180;text(cos((tRateSum+tRate/2).*pi.*2)*i,sin((tRateSum+tRate/2).*pi.*2)*i,NameCell{i}(j,:)+" ",FontProp{:},...'Rotation',rotation,'HorizontalAlignment','right')elsetext(cos((tRateSum+tRate/2).*pi.*2)*i,sin((tRateSum+tRate/2).*pi.*2)*i," "+NameCell{i}(j,:),FontProp{:},...'Rotation',rotation)endendtRateSum = tRateSum+tRate;end
end
% 绘制最外圈饼状图
tRateSum = 0;
tNameCell = Table.(NameList{end-1});
for j = 1:size(VAL,1)tRate = VAL(j,end)./sum(VAL(:,end)); tTheta = [tRateSum+tT.*tRate,tRateSum+tRate-tT.*tRate].*pi.*2;tR = [tT.*0+size(VAL,2),tT.*0+size(VAL,2)+1];tCN = VAL(j,1);fill(cos(tTheta).*tR,sin(tTheta).*tR,CList(tCN,:).*0.8^(size(VAL,2)-1)+...[1,1,1].*(1-0.8^(size(VAL,2)-1)),'EdgeColor',[1,1,1],'LineWidth',1)rotation = (tRateSum+tRate/2)*360;if tRate > TextThresholdif rotation>90&&rotation<270rotation=rotation+180;text(cos((tRateSum+tRate/2).*pi.*2)*size(VAL,2),sin((tRateSum+tRate/2).*pi.*2)*size(VAL,2),tNameCell(IDX(j),:)+" ",FontProp{:},...'Rotation',rotation,'HorizontalAlignment','right')elsetext(cos((tRateSum+tRate/2).*pi.*2)*size(VAL,2),sin((tRateSum+tRate/2).*pi.*2)*size(VAL,2)," "+tNameCell(IDX(j),:),FontProp{:},...'Rotation',rotation)endendtRateSum = tRateSum+tRate;
end


切向渐变

% 开始绘图
figure('Units','normalized','Position',[.2,.1,.52,.72]);
ax = gca; hold on
ax.DataAspectRatio = [1,1,1];
ax.XColor = 'none';
ax.YColor = 'none';
tT = linspace(0,1,100);
LCList = CList(1:length(NameCell{1}),:);
for i = 1:size(VAL,2)-1tRateSum = 0;tNum = length(NameCell{i});NCList = zeros(tNum,3);for j = 1:tNumtRate = sum(VAL(VAL(:,i) == j,end))./sum(VAL(:,end));  tTheta = [tRateSum+tT.*tRate,tRateSum+tRate-tT.*tRate].*pi.*2;tR = [tT.*0+i,tT.*0+i+1];if i == 1fill(cos(tTheta).*tR,sin(tTheta).*tR,CList(j,:),'EdgeColor',[1,1,1],'LineWidth',1)elsetCN = VAL(find(VAL(:,i) == j,1),i-1);tNN = j-VAL(find(VAL(:,i-1) == tCN,1),i)+1;tPN = length(unique(VAL(VAL(:,i-1) == tCN,i)));if mod(i,2)~=0tRN = tNN;elsetRN = tPN+1-tNN;end    NCList(j,:)=LCList(tCN,:).*0.8^(tRN-1)+[1,1,1].*(1-0.8^(tRN-1));fill(cos(tTheta).*tR,sin(tTheta).*tR,NCList(j,:),'EdgeColor',[1,1,1],'LineWidth',1)endrotation = (tRateSum+tRate/2)*360;if tRate > TextThresholdif rotation>90&&rotation<270rotation=rotation+180;text(cos((tRateSum+tRate/2).*pi.*2)*i,sin((tRateSum+tRate/2).*pi.*2)*i,NameCell{i}(j,:)+" ",FontProp{:},...'Rotation',rotation,'HorizontalAlignment','right')elsetext(cos((tRateSum+tRate/2).*pi.*2)*i,sin((tRateSum+tRate/2).*pi.*2)*i," "+NameCell{i}(j,:),FontProp{:},...'Rotation',rotation)endendtRateSum = tRateSum+tRate;endif i ~=1LCList=NCList;end
end
% 绘制最外圈饼状图
tRateSum = 0;
tNameCell = Table.(NameList{end-1});
NCList = zeros(size(VAL,1),3);
for j = 1:size(VAL,1)tRate = VAL(j,end)./sum(VAL(:,end)); tTheta = [tRateSum+tT.*tRate,tRateSum+tRate-tT.*tRate].*pi.*2;tR = [tT.*0+size(VAL,2),tT.*0+size(VAL,2)+1];tCN = VAL(j,size(VAL,2)-1);tNN = j-find(VAL(:,size(VAL,2)-1) == tCN,1)+1;tPN = sum(VAL(:,size(VAL,2)-1) == tCN);if mod(size(VAL,2),2)~=0tRN = tNN;elsetRN = tPN+1-tNN;endNCList(j,:)=LCList(tCN,:).*0.8^(tRN-1)+[1,1,1].*(1-0.8^(tRN-1));fill(cos(tTheta).*tR,sin(tTheta).*tR,NCList(j,:),'EdgeColor',[1,1,1],'LineWidth',1)rotation = (tRateSum+tRate/2)*360;if tRate > TextThresholdif rotation>90&&rotation<270rotation=rotation+180;text(cos((tRateSum+tRate/2).*pi.*2)*size(VAL,2),sin((tRateSum+tRate/2).*pi.*2)*size(VAL,2),tNameCell(IDX(j),:)+" ",FontProp{:},...'Rotation',rotation,'HorizontalAlignment','right')elsetext(cos((tRateSum+tRate/2).*pi.*2)*size(VAL,2),sin((tRateSum+tRate/2).*pi.*2)*size(VAL,2)," "+tNameCell(IDX(j),:),FontProp{:},...'Rotation',rotation)endendtRateSum = tRateSum+tRate;
end


完整代码(径向)

就是前面的代码顺着复制下来,可以换成自己的数据和颜色:
篇幅有限就只先给出径向渐变完整代码,切向渐变代码就光把最后一段稍微一更换即可:

% @author:slandarer%% ========================================================================
% 随机生成一组数据,可将 Table 自行更换
rng(1)
ULList = 'ABCD';
LLList = 'abcd';rowNum = 50;
idx1   = randi([1,length(ULList)],[1,rowNum]);
idx2   = randi([1,3],[rowNum,1]);
Name1  = ULList(idx1'*ones(1,4));
Name2  = [LLList(idx1'*ones(1,4)),num2str(idx2)];
Name3  = [LLList(idx1)',num2str(idx2),...char(45.*ones(rowNum,1)),char(randi([97,122],[rowNum,5]))];
Value  = rand([rowNum,1]);
Table  = table(Name1,Name2,Name3,Value);%% ========================================================================
% 利用 grp2idx 进行分类,利用 sortrows 将相同类归在一起
NameList  = Table.Properties.VariableNames;
NameNum   = length(NameList)-1;
NameCell{NameNum} = ' ';
valueList = zeros(length(Table.(NameList{1})),NameNum);
for i = 1:NameNum-1tName = Table.(NameList{i});tUniq = unique(tName,'rows');NameCell{i} = tUniq;ind = grp2idx([tUniq;tName]);ind(1:length(tUniq)) = [];valueList(:,i) = ind;
end
valueList(:,end) = -Table.(NameList{end});
[VAL,IDX] = sortrows(valueList,1:size(valueList,2));
VAL(:,end) = -VAL(:,end);
%% ========================================================================
% 此处可以设置配色
CList=[0.3882    0.5333    0.70591.0000    0.6824    0.20390.9373    0.4353    0.41570.5490    0.7608    0.79220.3333    0.6784    0.53730.7647    0.7373    0.24710.7333    0.4627    0.57650.7294    0.6275    0.58040.6627    0.7098    0.68240.4627    0.4627    0.4627];
% 在这可修改字体
FontProp = {'FontSize',12,'Color',[0,0,0]};
% 在这可设置比例低于多少的部分不显示文字
TextThreshold = 0.012;
%% ========================================================================
% 开始绘图
figure('Units','normalized','Position',[.2,.1,.52,.72]);
ax = gca; hold on
ax.DataAspectRatio = [1,1,1];
ax.XColor = 'none';
ax.YColor = 'none';
tT = linspace(0,1,100);
for i = 1:size(VAL,2)-1tRateSum = 0;tNum = length(NameCell{i});for j = 1:tNumtRate = sum(VAL(VAL(:,i) == j,end))./sum(VAL(:,end));  tTheta = [tRateSum+tT.*tRate,tRateSum+tRate-tT.*tRate].*pi.*2;tR = [tT.*0+i,tT.*0+i+1];if i == 1fill(cos(tTheta).*tR,sin(tTheta).*tR,CList(j,:),'EdgeColor',[1,1,1],'LineWidth',1)elsetCN = VAL(find(VAL(:,i) == j,1),1);fill(cos(tTheta).*tR,sin(tTheta).*tR,...CList(tCN,:).*0.8^(i-1)+[1,1,1].*(1-0.8^(i-1)),'EdgeColor',[1,1,1],'LineWidth',1)endrotation = (tRateSum+tRate/2)*360;if tRate > TextThresholdif rotation>90&&rotation<270rotation=rotation+180;text(cos((tRateSum+tRate/2).*pi.*2)*i,sin((tRateSum+tRate/2).*pi.*2)*i,NameCell{i}(j,:)+" ",FontProp{:},...'Rotation',rotation,'HorizontalAlignment','right')elsetext(cos((tRateSum+tRate/2).*pi.*2)*i,sin((tRateSum+tRate/2).*pi.*2)*i," "+NameCell{i}(j,:),FontProp{:},...'Rotation',rotation)endendtRateSum = tRateSum+tRate;end
end
% 绘制最外圈饼状图
tRateSum = 0;
tNameCell = Table.(NameList{end-1});
for j = 1:size(VAL,1)tRate = VAL(j,end)./sum(VAL(:,end)); tTheta = [tRateSum+tT.*tRate,tRateSum+tRate-tT.*tRate].*pi.*2;tR = [tT.*0+size(VAL,2),tT.*0+size(VAL,2)+1];tCN = VAL(j,1);fill(cos(tTheta).*tR,sin(tTheta).*tR,CList(tCN,:).*0.8^(size(VAL,2)-1)+...[1,1,1].*(1-0.8^(size(VAL,2)-1)),'EdgeColor',[1,1,1],'LineWidth',1)rotation = (tRateSum+tRate/2)*360;if tRate > TextThresholdif rotation>90&&rotation<270rotation=rotation+180;text(cos((tRateSum+tRate/2).*pi.*2)*size(VAL,2),sin((tRateSum+tRate/2).*pi.*2)*size(VAL,2),tNameCell(IDX(j),:)+" ",FontProp{:},...'Rotation',rotation,'HorizontalAlignment','right')elsetext(cos((tRateSum+tRate/2).*pi.*2)*size(VAL,2),sin((tRateSum+tRate/2).*pi.*2)*size(VAL,2)," "+tNameCell(IDX(j),:),FontProp{:},...'Rotation',rotation)endendtRateSum = tRateSum+tRate;
end

以上以及是完整代码,若日后代码有更新可在以下gitee仓库查看:

https://gitee.com/slandarer/spdraw/

这篇关于MATLAB | 两种上色方式的旭日图绘制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/282184

相关文章

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

Linux挂载linux/Windows共享目录实现方式

《Linux挂载linux/Windows共享目录实现方式》:本文主要介绍Linux挂载linux/Windows共享目录实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录文件共享协议linux环境作为服务端(NFS)在服务器端安装 NFS创建要共享的目录修改 NFS 配

Vue3视频播放组件 vue3-video-play使用方式

《Vue3视频播放组件vue3-video-play使用方式》vue3-video-play是Vue3的视频播放组件,基于原生video标签开发,支持MP4和HLS流,提供全局/局部引入方式,可监听... 目录一、安装二、全局引入三、局部引入四、基本使用五、事件监听六、播放 HLS 流七、更多功能总结在 v

Java8 Collectors.toMap() 的两种用法

《Java8Collectors.toMap()的两种用法》Collectors.toMap():JDK8中提供,用于将Stream流转换为Map,本文给大家介绍Java8Collector... 目录一、简单介绍用法1:根据某一属性,对对象的实例或属性做映射用法2:根据某一属性,对对象集合进行去重二、Du

Java发送SNMP至交换机获取交换机状态实现方式

《Java发送SNMP至交换机获取交换机状态实现方式》文章介绍使用SNMP4J库(2.7.0)通过RCF1213-MIB协议获取交换机单/多路状态,需开启SNMP支持,重点对比SNMPv1、v2c、v... 目录交换机协议SNMP库获取交换机单路状态获取交换机多路状态总结交换机协议这里使用的交换机协议为常

k8s admin用户生成token方式

《k8sadmin用户生成token方式》用户使用Kubernetes1.28创建admin命名空间并部署,通过ClusterRoleBinding为jenkins用户授权集群级权限,生成并获取其t... 目录k8s admin用户生成token创建一个admin的命名空间查看k8s namespace 的

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

Python绘制TSP、VRP问题求解结果图全过程

《Python绘制TSP、VRP问题求解结果图全过程》本文介绍用Python绘制TSP和VRP问题的静态与动态结果图,静态图展示路径,动态图通过matplotlib.animation模块实现动画效果... 目录一、静态图二、动态图总结【代码】python绘制TSP、VRP问题求解结果图(包含静态图与动态图

Pandas处理缺失数据的方式汇总

《Pandas处理缺失数据的方式汇总》许多教程中的数据与现实世界中的数据有很大不同,现实世界中的数据很少是干净且同质的,本文我们将讨论处理缺失数据的一些常规注意事项,了解Pandas如何表示缺失数据,... 目录缺失数据约定的权衡Pandas 中的缺失数据None 作为哨兵值NaN:缺失的数值数据Panda

java读取excel文件为base64实现方式

《java读取excel文件为base64实现方式》文章介绍使用ApachePOI和EasyExcel处理Excel文件并转换为Base64的方法,强调EasyExcel适合大文件且内存占用低,需注意... 目录使用 Apache POI 读取 Excel 并转换为 Base64使用 EasyExcel 处