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

news2024/11/17 5:20:54

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

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

还是挺酷的,近期没啥空单独开发出一个支持更多上色模式的类,大家可以先根据本文提供的代码先自行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-1
    tName = 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.7059
    1.0000    0.6824    0.2039
    0.9373    0.4353    0.4157
    0.5490    0.7608    0.7922
    0.3333    0.6784    0.5373
    0.7647    0.7373    0.2471
    0.7333    0.4627    0.5765
    0.7294    0.6275    0.5804
    0.6627    0.7098    0.6824
    0.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)-1
    tRateSum = 0;
    tNum = length(NameCell{i});
    for j = 1:tNum
        tRate = 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 == 1
            fill(cos(tTheta).*tR,sin(tTheta).*tR,CList(j,:),'EdgeColor',[1,1,1],'LineWidth',1)
        else
            tCN = 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)
        end
        
        rotation = (tRateSum+tRate/2)*360;
        if tRate > TextThreshold
        if rotation>90&&rotation<270
            rotation=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')
        else
            text(cos((tRateSum+tRate/2).*pi.*2)*i,sin((tRateSum+tRate/2).*pi.*2)*i," "+NameCell{i}(j,:),FontProp{:},...
                'Rotation',rotation)
        end
        end
        tRateSum = 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 > TextThreshold
    if rotation>90&&rotation<270
        rotation=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')
    else
        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)
    end
    end
    tRateSum = 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)-1
    tRateSum = 0;
    tNum = length(NameCell{i});
    NCList = zeros(tNum,3);
    for j = 1:tNum
        tRate = 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 == 1
            fill(cos(tTheta).*tR,sin(tTheta).*tR,CList(j,:),'EdgeColor',[1,1,1],'LineWidth',1)
        else
            tCN = 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)~=0
                tRN = tNN;
            else
                tRN = 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)
        end
        
        rotation = (tRateSum+tRate/2)*360;
        if tRate > TextThreshold
        if rotation>90&&rotation<270
            rotation=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')
        else
            text(cos((tRateSum+tRate/2).*pi.*2)*i,sin((tRateSum+tRate/2).*pi.*2)*i," "+NameCell{i}(j,:),FontProp{:},...
                'Rotation',rotation)
        end
        end
        tRateSum = tRateSum+tRate;
    end
    if i ~=1
        LCList=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)~=0
        tRN = tNN;
    else
        tRN = 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)
    rotation = (tRateSum+tRate/2)*360;
    if tRate > TextThreshold
    if rotation>90&&rotation<270
        rotation=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')
    else
        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)
    end
    end
    tRateSum = 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-1
    tName = 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.7059
    1.0000    0.6824    0.2039
    0.9373    0.4353    0.4157
    0.5490    0.7608    0.7922
    0.3333    0.6784    0.5373
    0.7647    0.7373    0.2471
    0.7333    0.4627    0.5765
    0.7294    0.6275    0.5804
    0.6627    0.7098    0.6824
    0.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)-1
    tRateSum = 0;
    tNum = length(NameCell{i});
    for j = 1:tNum
        tRate = 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 == 1
            fill(cos(tTheta).*tR,sin(tTheta).*tR,CList(j,:),'EdgeColor',[1,1,1],'LineWidth',1)
        else
            tCN = 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)
        end
        
        rotation = (tRateSum+tRate/2)*360;
        if tRate > TextThreshold
        if rotation>90&&rotation<270
            rotation=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')
        else
            text(cos((tRateSum+tRate/2).*pi.*2)*i,sin((tRateSum+tRate/2).*pi.*2)*i," "+NameCell{i}(j,:),FontProp{:},...
                'Rotation',rotation)
        end
        end
        tRateSum = 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 > TextThreshold
    if rotation>90&&rotation<270
        rotation=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')
    else
        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)
    end
    end
    tRateSum = tRateSum+tRate;
end

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1130131.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

12、Python -- if 分支 的讲解和使用

目录 程序结构顺序结构分支结构分支结构注意点不要忘记冒号 if条件的类型if条件的逻辑错误if表达式pass语句 程序流程 分支结构 分支结构的注意点 if条件的类型 if语句的逻辑错误 if表达式 程序结构 Python同样提供了现代编程语言都支持的三种流程 顺序结构 分支结构 循环结构…

CPU核检测

import psutil num_cpus psutil.cpu_count(logicalFalse) print(num_cpus) num_cpus psutil.cpu_count(logicalTrue) print(num_cpus)结果如下 可以看到这个结果是不同的

fiddler导出录制脚本并导出jmter脚本文件

1、fiddler导出录制脚本 可以通过save保存录制的脚本&#xff1a; 也可以选中这些链接&#xff0c;点击右键-->save-->select sessions -->选择要导入的文件 2、导入录制的脚本 再fiddler-->file--->load ARCHIVERS--->选择刚导出的.saz文件&#xff0c;正…

01-初识VUE3

01.初识VUE3 1.创建VUE3项目 1).使用 vue-cli 创建 ## 查看vue/cli版本&#xff0c;确保vue/cli版本在4.5.0以上 vue --version ## 安装或者升级你的vue/cli npm install -g vue/cli ## 创建 vue create vue_test ## 启动 cd vue_test npm run serve2).使用 vite 创建 ## 创…

吃豆人C语言开发—Day2 需求分析 流程图 原型图

目录 需求分析 流程图 原型图 主菜单&#xff1a; 设置界面&#xff1a; 地图选择&#xff1a; 游戏界面&#xff1a; 收集完成提示&#xff1a; 游戏胜利界面&#xff1a; 游戏失败界面 死亡提示&#xff1a; 这个项目是我和朋友们一起开发的&#xff0c;在此声明一下…

【C#】委托与事件

目录 一、委托 1.什么是委托 2.委托类型的声明与初始化 3.委托类型引用方法的调用 4.使用委托类型作为方法的参数 5.Action委托 6.Func委托 7.通用类型冒泡排序 8.多播委托 二、Lambda表达式 1.匿名方法 2.Lambda表达式表示匿名方法 三、事件 1.什么是事件 2.事件…

Django viewsets 视图集与 router 路由实现评论接口开发

正常来说遵循restful风格编写接口&#xff0c;定义一个类包含了 get post delete put 四种请求方式&#xff0c;这四种请求方式是不能重复的 例如:获取单条记录和多条记录使用的方式都是get&#xff0c;如果两个都要实现的话那么得定义两个类&#xff0c;因为在同一个类中不能有…

【vue3 】 创建项目vscode 提示无法找到模块

使用命令创建 vue3 创建新应用 npm create vuelatest会看到一些可选功能的询问&#xff1f; √ 请输入项目名称&#xff1a; … vue-project √ 是否使用 TypeScript 语法&#xff1f; … 否 / 是 √ 是否启用 JSX 支持&#xff1f; … 否 / 是 √ 是否引入 Vue Router 进行单…

useReducer的使用以及与useState、useImmerReducer的对比使用

前言 对于拥有许多状态更新逻辑的组件来说&#xff0c;过于分散的事件处理程序可能会影响代码的可读性。这种情况&#xff0c;可以将组件的所有状态更新逻辑整合到一个外部函数中&#xff0c;这个函数就是reducer。 使用 useReducer(reducer, initialArg, init?) 参数 redu…

电力通信与泛在电力物联网技术的应用与发展-安科瑞黄安南

摘要&#xff1a;随着我国社会经济的快速发展&#xff0c;我国科技实力得到了非常大的提升&#xff0c;当前互联网通信技术在社会中得到了广泛的应用。随着电力通信技术的快速发展与更新&#xff0c;泛在电力物联网建设成为电力通讯发展的重要方向。本文已泛在电力物联网系统为…

化工园区数字孪生可视化管控平台,赋予园区安全环保智慧发展

化工行业作为国民经济的支柱和工业发展的引擎&#xff0c;对安全生产、环保节能、应急管控有着很高的要求。目前国内外化工园区面临安全和环保两大压力。为有效解决这两大难题&#xff0c;巨蟹数科综合运用物联网、数字孪生等新一代信息技术&#xff0c;建设了数字孪生园区智慧…

Docker下安装MSSQL并使用Navicat远程连接(备忘录)

Docker下安装MSSQL并使用Navicat远程连接 一. Docker下安装MSSQL备忘录一、安装SQL Server1、从 Microsoft 容器注册表中请求 SQL Server 2022 (16.x) Linux 容器映像:注意:2、运行这个cu5的版本下表对前一个 docker run 示例中的参数进行了说明:3、看这个MSSQL运行没有?用…

JAVA基础——编译器报告的错误信息总结

1. Invalid character&#xff08;无效字符&#xff09; 中英文符号错误 2. 数组的常见异常 数组越界异常ArrayIndexOutOfBoundsException: 在使用索引访问数组的元素时超出了数组的索引范围0~length-1。 空指针异常NullPointerException&#xff1a; 在使用变量引用一个数…

CSS - 常用属性和布局方式

目录 前言 一、常用属性 1.1、字体相关 1.2、文本相关 1.3、背景相关 1.3.1、背景颜色 1.3.2、背景图片 1.4、圆角边框 二、常用布局相关 2.1、display 2.2、盒子模型 2.2.1、基本概念 2.2.2、border 边框 2.2.3、padding 内边距 2.2.4、margin 外边距 2.3、弹…

【Android】MQTT

目录 MQTT 协议简介应用场景优点缺点 部署服务端下载安装包启动服务器 搭建客户端下载SDK添加依赖配置MQTT服务和权限建立连接订阅主题发布消息取消订阅断开连接 MQTT客户端工具最终效果实现传感器数据采集与监测功能思路 MQTT 协议 简介 MQTT&#xff08;Message Queuing Te…

【目标跟踪】多目标跟踪测距

文章目录 前言python代码&#xff08;带注释&#xff09;main.pysort.pykalman.pydistance.py 结语 前言 先放效果图。目标框内左上角&#xff0c;显示的是目标距离相机的纵向距离。目标横向距离、速度已求出&#xff0c;没在图片展示。这里不仅仅实现对目标检测框的跟踪&#…

【Django restframework】django跨域问题,解决PUT/PATCH/DELETE用ajax请求无法提交数据的问题

【Django restframework】django跨域问题&#xff0c;解决PUT/PATCH/DELETE用ajax请求无法提交数据的问题 1 问题描述&#xff1a; 我用restframework(ModelSerializerGenericApiView)开发了一组符合RestFul接口标准的接口&#xff0c;这意味着它将支持客户端发来的GET、POST、…

矢量图形编辑软件 illustrator 2023 mac 中文软件特点

illustrator 2023 mac是一款矢量图形编辑软件&#xff0c;用于创建和编辑排版、图标、标志、插图和其他类型的矢量图形。 illustrator 2023 mac软件特点 矢量图形&#xff1a;illustrator创建的图形是矢量图形&#xff0c;可以无限放大而不失真&#xff0c;这与像素图形编辑软…

【接口测试】Jmeter接口实战-Dubbo接口+造10W数据测试(详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、Windows环境通…

Harmony 个人中心(页面交互、跳转、导航、容器组件)

个人中心 前言正文一、创建工程二、登录① 更换启动页面② 拓展修饰符③ 页面跳转④ 等待进度条 三、导航栏四、首页① 轮播图② 网格列表 五、我的① 带参数跳转 六、源码 前言 今天是1024&#xff0c;祝各位程序员们&#xff0c;钱多事少离家近&#xff0c;不秃也强bug黄。在…