当前位置: 首页 > news >正文

MATLAB | 绘图复刻(十八) | K-means 聚类分组热图

嘿,又双叒叕又双叒叕好久不见了,这期来个后台问的分组的热图,实际上就是绘制热图然后根据分组画一些线,但是matlab自带的热图heatmap不支持hold on操作,因此我们直接用pcolor来画,原图和复刻效果如下:

直接看步骤:

步骤解读

0 数据准备

这边我随机生成了一些数据,大家可以换成自己的,CName是分类后每个类的名字,大家可以增加一些识别每个类是什么种类的步骤,来将其换成自己的类名:

% 随便生成一些随机数据
rng(5)
Data = rand(50,10).*((1:10) + rand(1,10)) + randi([1,8],[50,1]);
Data = Data(:); Data = Data([end,1:end-1]); Data = reshape(Data, 50, []);% 可以直接将上面部分删掉,然后
% Data = []% 自己的数据K = 8; % kmeans 分组数
CName = compose('Class-%d', 1:K);% 将相同组数据放在一起,并计算相关矩阵
[Class, Ind] = sort(kmeans(Data, K));
HMat = corr(Data(Ind,:).');

1 创建图窗并修饰

主要是设置坐标区域比例,增添X/Y轴刻度标签,增加标题,改改字体等:

%  坐标区域修饰
figure('Units','normalized', 'Position',[.1,.1,.6,.8])
ax = gca;
ax.NextPlot = 'add';
ax.Box = 'on';
ax.PlotBoxAspectRatio = [1,1,1];
ax.FontName = 'Times New Roman';
ax.FontSize = 14;
ax.YDir = 'reverse';
TickPos = find(diff([0;Class;K+1]) == 1);
ax.XTick = (TickPos(1:end-1) + TickPos(2:end) - 1)./2 - .5;
ax.YTick = ax.XTick;
ax.XTickLabel = CName;
ax.YTickLabel = CName;
ax.XTickLabelRotation = 30;
% 修改标题
ax.Title.String = 'XXXXXX K-means Centroid';
ax.Title.FontSize = 24;
ax.Title.VerticalAlignment = 'bottom';

2 绘制热图

由于pcolor每个格子的颜色是由上下左右四个格点的数值决定(比如左上角数值),因此直接用矩阵话最后一行最后一列的数值就不会被使用,导致画出来的热图少了一行一列,因此使用pcolor函数前需要先给矩阵增加一行一列NaN。

这部分代码最后一行的如果把注释符号去掉的话,能够隐藏边缘线。

% 绘制热图
N = size(Data, 1);
X = 0:N;
HMat(end+1, :) = nan;
HMat(:, end+1) = nan;
PHdl = pcolor(X, X, HMat);
PHdl.EdgeColor = [.3,.3,.3]; 
% PHdl.EdgeColor = 'none'; 

3 添加分组线

% 绘制分组线
for i = 2:Kplot(ax, TickPos([i,i]) - 1, [0,N], 'Color','k', 'LineWidth',2)plot(ax, [0,N], TickPos([i,i]) - 1, 'Color','k', 'LineWidth',2)
end

4 绘制colorbar并调整颜色图

colorbar()
colormap(flipud(turbo))
clim([-1,1])% colormap(slanCM(134))

大家可以尝试一下以下工具来获得更多种类的colormap:

  • https://www.mathworks.com/matlabcentral/fileexchange/120088-200-colormap

比如其中136号配色:

134号配色:

114号配色:


完整代码

% Grouped heatmap% 随便生成一些随机数据
rng(5)
Data = rand(50,10).*((1:10) + rand(1,10)) + randi([1,8],[50,1]);
Data = Data(:); Data = Data([end,1:end-1]); Data = reshape(Data, 50, []);% 可以直接将上面部分删掉,然后
% Data = []% 自己的数据K = 8; % kmeans 分组数
CName = compose('Class-%d', 1:K);% 将相同组数据放在一起,并计算相关矩阵
[Class, Ind] = sort(kmeans(Data, K));
HMat = corr(Data(Ind,:).');%% 绘图部分
%  坐标区域修饰
figure('Units','normalized', 'Position',[.1,.1,.6,.8])
ax = gca;
ax.NextPlot = 'add';
ax.Box = 'on';
ax.PlotBoxAspectRatio = [1,1,1];
ax.FontName = 'Times New Roman';
ax.FontSize = 14;
ax.YDir = 'reverse';
TickPos = find(diff([0;Class;K+1]) == 1);
ax.XTick = (TickPos(1:end-1) + TickPos(2:end) - 1)./2 - .5;
ax.YTick = ax.XTick;
ax.XTickLabel = CName;
ax.YTickLabel = CName;
ax.XTickLabelRotation = 30;
% 修改标题
ax.Title.String = 'XXXXXX K-means Centroid';
ax.Title.FontSize = 24;
ax.Title.VerticalAlignment = 'bottom';% 绘制热图
N = size(Data, 1);
X = 0:N;
HMat(end+1, :) = nan;
HMat(:, end+1) = nan;
PHdl = pcolor(X, X, HMat);
PHdl.EdgeColor = [.3,.3,.3]; 
% PHdl.EdgeColor = 'none'; % 绘制分组线
for i = 2:Kplot(ax, TickPos([i,i]) - 1, [0,N], 'Color','k', 'LineWidth',2)plot(ax, [0,N], TickPos([i,i]) - 1, 'Color','k', 'LineWidth',2)
end% 绘制colorbar并调整颜色图
colorbar()
colormap(flipud(turbo))
clim([-1,1])% colormap(slanCM(134))

以上已经是完整代码,如果懒得复制可以去以下gitee仓库获取:

  • https://gitee.com/slandarer/PLTreprint/

http://www.mrgr.cn/news/55056.html

相关文章:

  • STM32软件模拟I2C的实现方式(一)
  • OpenAI GPT-o1实现方案记录与梳理
  • 3.1.1ReactOS系统中搜索给定长度的空间地址区间函数的实现
  • 信雅纳Chimera 100G网络损伤仪助力Parallel Wireless开展5G RAN无线前传网络的损伤模拟
  • C++智能指针及其应用
  • 程序员必须掌握的消息中间件-RocketMQ
  • 大模型的多样性:从语言处理到多模态智能
  • 深入解析:Nacos AP 模式的实现原理与应用场景
  • ACM与蓝桥杯竞赛指南 基本输入输出格式一
  • Linux命令进阶·vi\vim编辑器详细命令介绍
  • 【Java知识】java基础-开发一个自定义注解
  • Lesson10---list
  • 江恩理论(Gann Theory)
  • SQL Injection | SQL 注入 —— 报错盲注
  • 【AIGC】智能创作的革新与未来展望
  • 基于模型设计的智能平衡移动机器人-基础实验SCI
  • Win11右键默认显示更多选项
  • 从零开始搭建一个高可用的HBase集群
  • C++ -string -常见用法5
  • DS快速排序和归并排序的非递归实现(16)
  • 【Javaee】网络编程-TCP Socket
  • Linux常用命令详细解析(含完整命令演示过程)
  • windows C++ 有效利用异步代理库(二)
  • 上海市货运资格证二寸照片要求及手机拍照方法
  • C++编程语言:抽象机制:运算符重载(Bjarne Stroustrup)
  • PostgreSQL模板数据库template0和template1的异同点