Matlab 绘图布局全解析:从单图、叠图到子图(figure, plot, subplot, hold on)实战代码

Matlab 绘图布局全解析:从单图、叠图到子图(figure, plot, subplot, hold on)实战代码

1. Matlab绘图基础:从单图到多图的布局逻辑

第一次用Matlab画图时,我盯着屏幕上孤零零的一条正弦曲线发呆——这和我论文里需要的专业图表相差甚远。后来才发现,Matlab的绘图系统就像乐高积木,figure是画板,plot是画笔,而subplothold on就是连接件,通过不同组合能搭建出任意复杂的可视化结构。

单图绘制是最基础的技能,相当于绘画中的单色素描。比如要画正弦函数,代码简单得令人发指:

x = 0:0.1:2*pi; y = sin(x); figure; % 创建新画板 plot(x,y); % 绘制曲线

但实际工作中,我们常遇到更复杂的需求:比如比较不同参数的曲线、展示多维度数据、或者创建仪表盘式的监控界面。这时候就需要掌握三种进阶布局方式:

  1. 独立窗口模式:每个图表单独显示,适合需要全屏查看的细节图表
  2. 叠加绘图模式:多个曲线共享坐标轴,适合直接对比
  3. 子图阵列模式:将画板分割为矩阵区块,适合系统化展示

有次处理实验数据时,我需要同时观察温度、湿度、光照三个传感器的24小时变化。最初傻乎乎地开了三个窗口来回切换,直到发现subplot能像监控大屏那样并排显示所有数据,工作效率直接翻倍。

2. 独立窗口绘图:精准控制的单图呈现

当需要为每个数据集分配独立展示空间时,figure命令就是你的最佳搭档。它像给每幅画配了专属画框,避免不同图表相互干扰。我在分析音频频谱时就深有体会——不同频段的波形图分开显示,才能清晰看到谐波细节。

典型应用场景

  • 需要全屏查看细节的科研图表
  • 需要单独保存的高清图片
  • 需要交互操作(如缩放、平移)的复杂图形

看这个多窗口绘图的经典例子:

x = linspace(0, 2*pi, 100); figure(1); % 创建编号为1的窗口 plot(x, sin(x), 'r-'); % 红色实线 figure(2); % 创建编号为2的窗口 plot(x, cos(x), 'b--'); % 蓝色虚线 figure(3); plot(x, tan(x), 'g:'); % 绿色点线

这里有个实用技巧:给figure指定编号就像给房间贴门牌,之后可以用figure(n)快速切换。有次我同时调试8个电机控制曲线,就是靠编号管理才没乱套。

提示:用clf清除当前窗口内容,用close all关闭所有窗口,能避免内存堆积

窗口属性也可以精细调整。比如设置窗口位置和大小:

figure('Position', [100 100 800 600]) % [x位置 y位置 宽度 高度]

这个功能在准备学术海报时特别有用,可以精确控制每个图表的尺寸比例。

3. 叠加绘图:多曲线对比的艺术

科研中最常遇到的需求就是对比——比如比较理论值和实测值、不同算法结果、或者实验组对照组数据。hold on就是实现这种对比的神器,它让多个曲线在同一坐标系下叠加显示。

叠加绘图的三大优势

  1. 直观显示数据相对关系
  2. 节省版面空间
  3. 保持坐标尺度统一

还记得第一次用hold on的惨痛教训:画了三条曲线忘记添加图例,最后根本分不清哪条是哪条。现在我的标准操作流程是这样的:

x = 0:0.01:2*pi; figure; plot(x, sin(x), 'LineWidth', 2); hold on; % 开启叠加模式 plot(x, sin(2*x), '--', 'LineWidth', 1.5); plot(x, sin(3*x), ':', 'LineWidth', 1.5); hold off; % 关闭叠加模式 legend('sin(x)', 'sin(2x)', 'sin(3x)'); % 必须添加图例 grid on; % 显示网格线

颜色和线型的组合也有讲究。我习惯用鲜艳的红色表示理论值,蓝色表示实测值,虚线表示误差范围。Matlab提供了丰富的样式选项:

  • 颜色:r红、g绿、b蓝、c青、m品红、y黄、k黑、w
  • 线型:-实线、--虚线、:点线、-.点划线
  • 标记:o圆圈、+加号、*星号、.点、x叉号

当曲线超过5条时,建议使用colororder函数自定义颜色序列,避免使用相近色造成混淆。

4. 子图系统:专业级多图布局

论文插图和商业报表往往需要将多个关联图表系统化展示,这就是subplot的用武之地。它把画板分割成m行n列的矩阵,每个区块可以独立绘图。我最近做的传感器数据分析报告,就用2×3的子图阵列同时展示了时域波形、频谱图、散点图、直方图、累积分布和误差分析。

子图布局的核心要点

  • 先规划整体行列数
  • 合理安排图表位置
  • 保持风格统一但内容独立

基本语法subplot(m,n,p)中,p的编号顺序是从左到右、从上到下。比如这个经典布局:

x = linspace(0, 2*pi); figure; subplot(2,2,1); % 第1行第1列 plot(x, sin(x)); title('正弦函数'); subplot(2,2,2); % 第1行第2列 plot(x, cos(x)); title('余弦函数'); subplot(2,2,3); % 第2行第1列 plot(x, tan(x)); title('正切函数'); subplot(2,2,4); % 第2行第2列 plot(x, sin(x).*cos(x)); title('乘积函数');

实际使用中我发现几个实用技巧:

  1. subplot('position',[left bottom width height])可以创建非均匀子图
  2. 搭配sgtitle('总标题')给整个figure添加大标题
  3. 使用tight_subplot第三方函数解决间距问题

对于更复杂的布局,比如底部放一个长条形图,上方左右各放一个小图,可以这样实现:

figure; subplot(2,1,1); % 上方区域 subplot(2,2,3); % 左下 subplot(2,2,4); % 右下

这种灵活布局在制作PPT汇报图表时特别实用。

5. 混合技巧:解决实际工程问题

真实项目中的图表需求往往更复杂,需要组合使用各种技巧。有次处理卫星遥测数据,就需要在子图中叠加曲线,还要保持坐标轴同步。经过多次调试,最终找到了稳定可靠的代码结构。

典型复合场景解决方案

  1. 子图内叠加曲线
x = 0:0.1:2*pi; figure; subplot(1,2,1); plot(x, sin(x), 'b'); hold on; plot(x, cos(x), 'r'); hold off; subplot(1,2,2); plot(x, tan(x), 'g');

注意每个subplot都有自己的hold状态,需要分别控制。

  1. 动态更新子图
figure; h = subplot(1,1,1); for k = 1:5 plot(h, k, k^2, 'o'); hold(h, 'on'); % 指定axes句柄 drawnow; pause(0.5); end

通过保存axes句柄,可以精准控制特定子图的更新。

  1. 混合布局与格式统一
figure; % 上方大图 ax1 = subplot(2,1,1); plot(ax1, x, y1); ylabel(ax1, '振幅'); % 下方两个小图 ax2 = subplot(2,2,3); plot(ax2, x, y2); ax3 = subplot(2,2,4); plot(ax3, x, y3); % 统一设置 set([ax1 ax2 ax3], 'FontSize', 10, 'Box', 'on');

这种结构化编程方式让代码更易维护,图表风格也保持一致。

6. 高级美化:从能用