Matlab 绘图布局全解析:从单图、叠图到子图(figure, plot, subplot, hold on)实战代码
1. Matlab绘图基础:从单图到多图的布局逻辑
第一次用Matlab画图时,我盯着屏幕上孤零零的一条正弦曲线发呆——这和我论文里需要的专业图表相差甚远。后来才发现,Matlab的绘图系统就像乐高积木,figure是画板,plot是画笔,而subplot和hold on就是连接件,通过不同组合能搭建出任意复杂的可视化结构。
单图绘制是最基础的技能,相当于绘画中的单色素描。比如要画正弦函数,代码简单得令人发指:
x = 0:0.1:2*pi; y = sin(x); figure; % 创建新画板 plot(x,y); % 绘制曲线但实际工作中,我们常遇到更复杂的需求:比如比较不同参数的曲线、展示多维度数据、或者创建仪表盘式的监控界面。这时候就需要掌握三种进阶布局方式:
- 独立窗口模式:每个图表单独显示,适合需要全屏查看的细节图表
- 叠加绘图模式:多个曲线共享坐标轴,适合直接对比
- 子图阵列模式:将画板分割为矩阵区块,适合系统化展示
有次处理实验数据时,我需要同时观察温度、湿度、光照三个传感器的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就是实现这种对比的神器,它让多个曲线在同一坐标系下叠加显示。
叠加绘图的三大优势:
- 直观显示数据相对关系
- 节省版面空间
- 保持坐标尺度统一
还记得第一次用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('乘积函数');实际使用中我发现几个实用技巧:
- 用
subplot('position',[left bottom width height])可以创建非均匀子图 - 搭配
sgtitle('总标题')给整个figure添加大标题 - 使用
tight_subplot第三方函数解决间距问题
对于更复杂的布局,比如底部放一个长条形图,上方左右各放一个小图,可以这样实现:
figure; subplot(2,1,1); % 上方区域 subplot(2,2,3); % 左下 subplot(2,2,4); % 右下这种灵活布局在制作PPT汇报图表时特别实用。
5. 混合技巧:解决实际工程问题
真实项目中的图表需求往往更复杂,需要组合使用各种技巧。有次处理卫星遥测数据,就需要在子图中叠加曲线,还要保持坐标轴同步。经过多次调试,最终找到了稳定可靠的代码结构。
典型复合场景解决方案:
- 子图内叠加曲线:
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状态,需要分别控制。
- 动态更新子图:
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句柄,可以精准控制特定子图的更新。
- 混合布局与格式统一:
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');这种结构化编程方式让代码更易维护,图表风格也保持一致。