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中Map的五种遍历方式实现与对比

《Java中Map的五种遍历方式实现与对比》其实Map遍历藏着多种玩法,有的优雅简洁,有的性能拉满,今天咱们盘一盘这些进阶偏基础的遍历方式,告别重复又臃肿的代码,感兴趣的小伙伴可以了解下... 目录一、先搞懂:Map遍历的核心目标二、几种遍历方式的对比1. 传统EntrySet遍历(最通用)2. Lambd

Spring Boot 处理带文件表单的方式汇总

《SpringBoot处理带文件表单的方式汇总》本文详细介绍了六种处理文件上传的方式,包括@RequestParam、@RequestPart、@ModelAttribute、@ModelAttr... 目录方式 1:@RequestParam接收文件后端代码前端代码特点方式 2:@RequestPart接

Springboot配置文件相关语法及读取方式详解

《Springboot配置文件相关语法及读取方式详解》本文主要介绍了SpringBoot中的两种配置文件形式,即.properties文件和.yml/.yaml文件,详细讲解了这两种文件的语法和读取方... 目录配置文件的形式语法1、key-value形式2、数组形式读取方式1、通过@value注解2、通过

java中4种API参数传递方式统一说明

《java中4种API参数传递方式统一说明》在Java中,我们可以使用不同的方式来传递参数给方法或函数,:本文主要介绍java中4种API参数传递方式的相关资料,文中通过代码介绍的非常详细,需要的... 目录1. 概述2. 参数传递方式分类2.1 Query Parameters(查询参数)2.2 Path

Python使用Matplotlib和Seaborn绘制常用图表的技巧

《Python使用Matplotlib和Seaborn绘制常用图表的技巧》Python作为数据科学领域的明星语言,拥有强大且丰富的可视化库,其中最著名的莫过于Matplotlib和Seaborn,本篇... 目录1. 引言:数据可视化的力量2. 前置知识与环境准备2.1. 必备知识2.2. 安装所需库2.3

MybatisPlus中几种条件构造器运用方式

《MybatisPlus中几种条件构造器运用方式》QueryWrapper是Mybatis-Plus提供的一个用于构建SQL查询条件的工具类,提供了各种方法如eq、ne、gt、ge、lt、le、lik... 目录版本介绍QueryWrapperLambdaQueryWrapperUpdateWrapperL

idea设置快捷键风格方式

《idea设置快捷键风格方式》在IntelliJIDEA中设置快捷键风格,打开IDEA,进入设置页面,选择Keymap,从Keymaps下拉列表中选择或复制想要的快捷键风格,点击Apply和OK即可使... 目录idea设www.chinasem.cn置快捷键风格按照以下步骤进行总结idea设置快捷键pyth

Linux镜像文件制作方式

《Linux镜像文件制作方式》本文介绍了Linux镜像文件制作的过程,包括确定磁盘空间布局、制作空白镜像文件、分区与格式化、复制引导分区和其他分区... 目录1.确定磁盘空间布局2.制作空白镜像文件3.分区与格式化1) 分区2) 格式化4.复制引导分区5.复制其它分区1) 挂载2) 复制bootfs分区3)

MyBatis中的两种参数传递类型详解(示例代码)

《MyBatis中的两种参数传递类型详解(示例代码)》文章介绍了MyBatis中传递多个参数的两种方式,使用Map和使用@Param注解或封装POJO,Map方式适用于动态、不固定的参数,但可读性和安... 目录✅ android方式一:使用Map<String, Object>✅ 方式二:使用@Param

SpringBoot返回文件让前端下载的几种方式

《SpringBoot返回文件让前端下载的几种方式》文章介绍了开发中文件下载的两种常见解决方案,并详细描述了通过后端进行下载的原理和步骤,包括一次性读取到内存和分块写入响应输出流两种方法,此外,还提供... 目录01 背景02 一次性读取到内存,通过响应输出流输出到前端02 将文件流通过循环写入到响应输出流