news 2026/9/14 4:59:11

Matlab热图绘制全攻略:从基础到专用热图实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Matlab热图绘制全攻略:从基础到专用热图实战

简介:一套面向Matlab初、中级学习者的专用热图绘制资源包,聚焦热图的多种定制化展现需求,适合计算机、电子信息工程、数学等专业在课程设计、毕业设计或科研绘图中参考借鉴。包内共有105个文件,以17个.m源代码文件为核心,覆盖基本使用、颜色映射、分组、树状图、多层结构等不同场景的Demo;另包含85张效果示例图、1份说明文档以及mlx实时脚本,便于逐段对照理解每一类热图的生成逻辑。目前已有1102人学习下载,适用于需要快速参考热图绘制思路、但需具备一定Matlab基础并能自行调试代码的读者。代码整体结构清晰,可重点参考SHeatmap、SClusterBlock、SDendrogram等模块,结合文档灵活调整配色、层级或分组方案,从而高效完成从数据矩阵到专用热图的呈现,提升可视化效率。

1. 拿到「基于Matlab绘制各种专用热图」这套资源包,先别急着解压看图片

搜索这个标题的人,大多数不是在找heatmap函数怎么用,而是手里已经有一批数据,想要能直接出图交差的脚本。生物信息学的差异基因表达谱、金融领域的相关性矩阵、工业现场的温度场分布,第一眼呈现方式基本都靠热图。既然标题附带「源码+图片+说明文档」三个交付物,这就不是一个简单的绘制脚本,而是一整套从数据到图表的工程化输出方案。我会按「数据特征判定图类型 → 用 MatLab 原生函数搭建绘制框架 → 按场景定制专用形态 → 批量导出与验证」这条路径来梳理。无论你拿到的是哪种语言版本的热图资源,最后落地的思路是一致的:热图的成败不在颜色好不好看,而在数据映射关系和坐标语义是否准确。

2. 热图的三层底层逻辑:数据归一化、颜色映射与坐标系

2.1 先定坐标系:离散分类轴还是连续数值轴

Matlab 的热图工具看起来多,其实只有两类坐标系。一类是heatmap函数生成的HeatmapChart对象,X 轴和 Y 轴是离散的分类标签(比如基因名、时间点、实验组别),单元格颜色对应数值大小。另一类是基于imagescpcolorsurf的连续坐标系热图,适合本身就带物理间距的数据(比如空间坐标、光谱波长、时间序列)。

这两种坐标系的选择决定了后续所有定制方向。HeatmapChart的优势是自带行列标签、可交互排序、能叠加分组颜色条;但它有一个麻烦:坐标轴不是传统axes,很多针对axes的旧版函数无法直接套用。反过来,imagesc走的是标准axes,可以用textlinepatch自由叠加元素,但标签需要手动设置。

% 离散分类热图:词频矩阵 words = {'TCP';'UDP';'HTTP';'MQTT'}; timePoints = {'T1';'T2';'T3';'T4'}; data = rand(4,4)*10; h = heatmap(timePoints, words, data); h.Title = '协议交互频次热图'; h.XLabel = '时间点'; h.YLabel = '协议类型';

这段代码定义了一个 4x4 的随机数据矩阵,行是协议类型,列是采样时间点。heatmap接收三个参数时,前两个是行列标签的 cell 数组,第三个是数值矩阵。关键是理解heatmap不做数据归一化,它只负责把数值线性映射到当前colormap的色阶上,矩阵里的原始值可以通过单元格悬停查看。

2.2 颜色映射:让「红色代表危险」这件事不出错

很多人画热图只调了一个colormap就收工,但专用热图的核心在于「颜色语义清晰」。Matlab 的colormap只是把当前 figure 的颜色查找表换掉,真正控制颜色与数值关系的参数是CLim(对HeatmapChart来说是CLimits)。默认情况下CLim会根据数据的最小最大值自动计算,这就是很多热图颜色发灰、对比度差的原因。

对于差异分析类的数据(比如基因表达上下调),我一般会用diverging色系,且强制让 0 值对应中间色阶。常见做法是设定CLim对称,比如数据范围是 -5 到 8,就把CLim设为[-8 8],这样比 0 小的值和比 0 大的值在视觉上才不会互相掩盖幅值。

% 连续数值热图的色阶截断 imagesc(data); colormap(flipud(redbluecmap)); % 白色在中间,红蓝两端 caxis([-8 8]); % 老版本写法,R2022a 之后用 clim colorbar;

提示:R2022a 开始caxis被标记为将要移除,新代码统一使用clim(gca, [-8 8])HeatmapChart对应的是h.CLimits = [-8 8]

热图颜色映射还有一个容易被忽略的坑:imagesc会把矩阵的第一个元素放在左上方,而heatmap第一个元素在左下方。如果你同时用两种方式画同一份数据,看起来像是上下翻转了,实际是 Y 轴方向的定义不同。统一校正 YDir 是一个必备习惯。

2.3 数据归一化:行归一、列归一还是全局归一

「各种专用热图」的「专用」二字,很大程度体现在归一化策略上。全局归一化适合所有数据同一量纲的场景;行归一化(z-score)适合不同样本间比较趋势;列归一化适合比较不同变量在同一样本上的表现。在资源包里最常见到的说明文档内容,其实是描述了这几种归一化分别适用于什么场景。

% 三种归一化方式对比 data = randn(50, 20); % 行 z-score 归一化(按行计算均值和标准差) rowNorm = (data - mean(data,2)) ./ std(data,0,2); % 列 min-max 归一化到 [0,1] colMin = min(data,[],1); colMax = max(data,[],1); colNorm = (data - colMin) ./ (colMax - colMin); % 全局百分比归一化 gNorm = (data - min(data(:))) ./ (max(data(:)) - min(data(:)));

选择归一化方式有一个判断标准:热图上每一行代表独立样本(比如多个基因在不同细胞系中的表达量),优先行归一化;每一列代表独立量纲的指标(比如身高、体重、血压),优先列归一化。如果所有数据是同一物理量的不同位置采样,比如温度场,那就不要归一化,保留绝对数值反而更有工程意义。

3. 把热图做成专用图:概率密度、富集气泡与环形聚类形态

3.1 概率密度热图:用 histcounts2 替代散点图

当数据量达到数万条记录时,散点图会出现严重的重叠遮蔽问题,此时应该画密度热图。原理是把二维平面划分为网格,统计每个格子内的样本点数量,再用颜色映射表示密度高低。这类图形在搜索引擎日志分析、传感器数据相关性检查中非常常见。

% 用 histcounts2 构建密度网格 n = 100000; x = randn(n,1) * 2 + 1; y = x .* 0.7 + randn(n,1) * 0.5; [N, Xedges, Yedges] = histcounts2(x, y, 50, 50); imagesc(Xedges(1:end-1), Yedges(1:end-1), log1p(N')); axis xy; % 修正 Y 轴方向,让坐标原点在左下角 colormap(parula); c = colorbar; c.Label.String = 'log(样本数+1)';

这里的N是 50x50 的计数矩阵,log1p把计数做对数压缩,避免出现个别高密度格子把整体色阶拉平。选用imagesc而不是heatmap,是因为密度热图的横纵坐标是连续数值,离散标签反而丢失空间信息。注意N需要转置,因为histcounts2返回的矩阵第一维对应 X 的区间,而imagesc的第一个参数对应 X 坐标。

3.2 相关性热图与显著性星号的叠加方法

相关性矩阵热图是「专用热图」里需求最稳定的一类。核心难点不是画颜色块,而是把显著性检验的 p 值转成星号并精确标注到对应单元格上。HeatmapChart对象支持CellLabelFormatFontColor,但想要星号和数值同时出现在一个格子里,需要一点变通。

% 相关性热图 + 显著性星号 data = randn(100, 6); [R, P] = corrcoef(data); % 生成星号矩阵 stars = strings(size(P)); stars(P < 0.001) = "***"; stars(P >= 0.001 & P < 0.01) = "**"; stars(P >= 0.01 & P < 0.05) = "*"; labels = strings(size(R)); labels(:) = compose("%.2f", R); for i = 1:size(R,1) for j = 1:size(R,2) if i ~= j labels(i,j) = labels(i,j) + " " + stars(i,j); end end end h = heatmap(compose("V%d",1:6), compose("V%d",1:6), R); h.CellLabelFormat = '%s'; h.CellLabelColor = 'k';

corrcoef一次返回两个矩阵:相关系数R和 p 值P。用逻辑索引生成星号矩阵,再和数值拼成一个字符串矩阵,最后用CellLabelFormat = '%s'HeatmapChart显示字符串内容。有一点必须注意:heatmap会把CellLabel自动替换为矩阵数值,当你传入字符串矩阵时,数值字段会失效,所以ColorData仍然要用原始相关系数矩阵。

3.3 聚类热图:clustergram 的分组与树状图修剪

带树状图的聚类热图(常见于差异表达基因分析、宏基因组分箱结果展示)在 Matlab 里不必手工做层级聚类再画树,clustergram函数已经封装了完整流程。但它的默认输出是针对生物信息学的,想要变成通用热图,需要调整聚类距离和显示参数。

% 用 clustergram 画聚类热图 geneData = randn(300, 12); cg = clustergram(geneData, ... 'Standardize', 'row', ... 'Cluster', 'all', ... 'RowLabels', compose("g%d", 1:300), ... 'ColumnLabels', compose("s%d", 1:12), ... 'Dendrogram', 15, ... 'Colormap', redbluecmap, ... 'DisplayRange', 3); % 为列添加分组颜色条 set(cg, 'ColumnGroupMarker', [1 1 1 2 2 2 3 3 3 4 4 4]);

Standardize默认是'none',对差异表达热图来说通常要设为'row',也就是对每一行做 z-score 标准化。Dendrogram参数控制展示的树状图分支数,15 表示最多显示 15 条分支,分支太多时视觉上就是一团乱麻。DisplayRange控制颜色的上下限,设置为 3 意味着 z-score 值超过 ±3 的颜色不再加深,这避免个别极端值拉跨整体色阶。

环形热图(或称圆形热图)是聚类热图的一种变体,适用于变量数量多、名称长、线性排列放不下的场景。实现方案是把数据转换到极坐标系中,沿圆周方向排列变量,沿径向方向表示数值大小。基础思路是用polarscatter把每个数据点画成极坐标中的色块,再叠加颜色映射,但更稳妥的方式是用heatmap输出后,把坐标轴隐藏,叠一层极坐标网格。

提示:如果不需要树状图,只是想把热图的行列顺序梳理出可复现的分组顺序,clustergram提供了cg.RowLabelscg.ColumnLabels读取重排后的顺序,你可以把这些顺序导出后在heatmap里复用,这样既能保留原矩阵数据,又能保持聚类的视觉分组。

3.4 三维热图:把 XYZ 散点变成等值面

标题热搜里出现了「三个维度的热图」和「决策曲线」,这类需求通常指的不是 3D 曲面,而是「X、Y 两个自变量 + Z 一个因变量」构成的响应面图。数理统计里叫响应曲面,工程领域叫热力图投影,本质是把散点数据插值到均匀网格上再显示。

% 散点插值成三维热图 x = randn(2000,1); y = randn(2000,1); z = exp(-(x.^2 + y.^2)) + randn(2000,1)*0.05; [Xq, Yq] = meshgrid(-3:0.1:3, -3:0.1:3); Zq = griddata(x, y, z, Xq, Yq, 'natural'); % 2D 投影热图(等值面) contourf(Xq, Yq, Zq, 20); colorbar; colormap(jet); axis equal;

griddata接受散点坐标和散点值,插值到meshgrid生成的均匀网格上。'natural'是自然邻域插值,对不均匀分布的散点效果最好,但计算量大;如果数据点超过 50000 个,优先改用'linear'。插值之后的contourf填充等值线图比surf的俯视图更适合打印。

三维热图还有一个分支,是带时序的翻转热图,即把数据矩阵画成surface格式,通过修改view的角度来同时展示两个维度的变化趋势。这类图不适合做定量分析,但信息密度大,适合做汇报。

4. 大数据量与多子图:热图的性能陷阱与批量导出参数

4.1 上万行矩阵的渲染加速方案

heatmapimagesc在面对大矩阵时的性能完全不在一个量级。heatmap的每个单元格都是一个图形对象,行数超过 500 时渲染极慢,内存占用还会指数增长。而imagesc本质是画一张纹理贴图,渲染速度与矩阵大小几乎无关,瓶颈只在颜色查找表的计算上。

% 大矩阵热图:统一用 imagesc 做底图 bigData = randn(2000, 100); imagesc(bigData); colormap(plasma); ax = gca; set(ax, 'XTick', 1:10:100, 'XTickLabel', compose("T%d", 1:10:100)); set(ax, 'YTick', 1:100:2000, 'YTickLabel', compose("Gene%d", 1:100:2000));

这里把 2000x100 的矩阵用imagesc一次性绘制,X 轴只标记每 10 个采样点,Y 轴每 100 行打一个标签,避免标签重叠。plasma是感知均匀的颜色映射,全彩色视觉上比jet更平滑,且不包含黑色区域。

4.2 多热图并排:tiledlayout 与 colorbar 对齐方案

当需要把趋势图、聚类热图、富集条目热图拼成一张大图时(常见的组合是「聚类热图+趋势图+富集条目」三联图),tiledlayoutsubplot更适合。它的TileSpacingPadding属性可以精确控制子图间距,而且colorbar可以通过Layout参数指定挂载到哪个 tile 上。

% 三联图布局:热图 + 趋势折线 + 富集条目热图 t = tiledlayout(1, 3, 'TileSpacing', 'compact'); % 左:聚类热图 nexttile; imagesc(randn(30, 8)); colormap(ax1, redbluecmap); title('聚类热图'); % 中:趋势折线 nexttile; plot(randn(8, 8)'); title('趋势图'); % 右:富集条目热图 nexttile; imagesc(randn(20, 15)); title('富集条目热图'); cb = colorbar; cb.Layout.Tile = 'east'; % 让 colorbar 只挂在最右侧

colorbar默认会压缩相邻子图的宽度,Layout.Tile = 'east'可以解决这个问题,它把 colorbar 作为独立 tile 放到最右侧,其他子图宽度自动适配,不再互相挤压。这个组合形态在差异基因分析和组学数据展示里几乎成为模板。

4.3 高清导出:exportgraphics 的参数组合

热图的最终去向是论文、报告或 PPT,导出清晰度直接决定观感。老式的print -dpng输出默认会带白边,分辨率还需要手动匹配PaperPosition。从 R2020a 开始exportgraphics成为推荐方案,支持按像素分辨率导出且自动裁剪白边。

% 高清导出参数模板 fig = figure('Color', 'w', 'Position', [100 100 1200 800]); % ... 在这里画热图及其标注 ... exportgraphics(fig, 'heatmap_output.png', 'Resolution', 300);

Resolution设置为 300 可以满足印刷需求,PPT 投屏 150 足够;'BackgroundColor', 'none'可以导出透明背景,适用于深色 PPT 主题。如果导出PDF格式,矢量图形会被保留,文字清晰度最高,但文件体积会膨胀。对于大数据量的热图,导出 PDF 往往比 PNG 大一个数量级,此时 PNG 优先。

导出前的字体检查同样重要,HeatmapChart的字体和字号独立于 figure 设置,需要在h.FontSize中单独指定。多子图场景中最快的方法是统一字体参数:

set(findall(fig, '-property', 'FontSize'), 'FontSize', 10);

5. 一个高兼容性的热图模板:截断、标注与可复用封装

资源包存在最核心的价值其实是提供「能直接复用」的代码骨架,而非某一类具体热图的绘制脚本。我会按「数据进、图片出」的思路做一个最小模板,把前面涉及的元素集中到一个函数里,参数通过Name-Value传入,适用于 80% 的专用热图需求。

function h = plotHeatmapTemplate(data, labelsX, labelsY, opts) arguments data (:,:) double labelsX (1,:) cell labelsY (1,:) cell opts.Title string = "热图" opts.ColorMap string = "parula" opts.CLim (1,2) double = [] opts.ShowValue logical = false opts.FontSize double = 10 end h = heatmap(labelsX, labelsY, data); h.Title = opts.Title; h.Colormap = opts.ColorMap; h.FontSize = opts.FontSize; if ~isempty(opts.CLim) h.CLimits = opts.CLim; end if opts.ShowValue h.CellLabelFormat = '%.2f'; else h.CellLabelFormat = 'none'; end end

arguments块是 R2019b 之后的语法,配合heatmap的行列标签参数定义,可以让不同数据源直接调用。这个模板解决的关键问题是:每次画热图时不再复制粘贴一整段代码,而是把可变参数(标题、色阶范围、是否显示数值)显式声明出来。

「如何验证热图画得对」是比「画出热图」更高级一层的能力。我的做法是三步验证法:

第一步验证数据映射。在heatmap创建后调用h.ColorData,应该与输入矩阵完全一致(或等比例缩放)。如果颜色与预期数值明显不符,先检查是否因为missing值导致的数据压缩。第二步验证坐标对应关系。悬停热图单元格,弹出的 DataTip 里显示的行列标签,必须和数据表索引一一对应。第三步验证颜色截断位置。在colorbar上取中间位置颜色,与colormap的中间行颜色比较,确认尾端截断是否生效。

颜色截断检查可以用一段很短的脚本自动化完成:

% 验证颜色截断是否正确对应 CLim cmap = colormap; n = size(cmap, 1); midColor = cmap(round(n/2), :); % 取当前 colorbar 中间值,对应的数据应为 CLim 的均值 expectedValue = mean(clim(gca)); disp(['热图中心色对应的数值: ', num2str(expectedValue)]);

如果你拿到手的某个热图资源,图片与源码画出来的效果不一致,优先排查数据文件是否被排序或过滤过,其次是检查CLim是否为'auto',最后看 colormap 是否被后一段代码意外覆盖。大多数「热图颜色不对」的问题,根源都不在绘图函数本身,而是脚本执行顺序里某个生成 colorbar 或设置 colormap 的副作用。把模板函数和验证脚本固定下来,「基于Matlab绘制各种专用热图」这件事才算真正闭环,而不是每次换一组数据就从头折腾一遍配色和坐标。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 4:59:03

OpenClaw框架解析:AI Agent开发与安全实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 4:56:57

EKF在非全向移动机器人定位中的MATLAB实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 4:55:13

AIGC幽默生成技术解析与实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 4:55:05

2026年五大记事软件评测与选型指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 4:54:58

FPGA创新设计实战:从硬件筑基到算法加速的完整工程路径

1. 这不是一场普通竞赛&#xff1a;FPGA创新设计赛道到底在考什么&#xff1f;FPGA创新设计赛道&#xff0c;光看名字容易误以为是“学生交个Verilog代码、跑个仿真就完事”的传统电子设计比赛。但实际接触过近年赛题的老师和带队教练都知道&#xff0c;这已经演变成一场横跨硬…

作者头像 李华