MATLAB伯德图绘制与打印优化:从建模到导出的完整指南

发布时间:2026/10/13 14:56:25
MATLAB伯德图绘制与打印优化:从建模到导出的完整指南 简介面向自动控制原理学习与工程应用这份工具包提供基于Matlab的伯德图坐标纸定制脚本适合控制类专业学生、科研人员及工程师快速生成规范化幅频和相频特性图纸。压缩包共4个文件含三个Matlab脚本文件与一份说明文档包体仅5KB轻量易用。目前已有1034人浏览学习。脚本围绕伯德图绘制函数封装支持自定义频率范围、轴刻度、子图布局与导出样式可生成1比1、2比1、2比2等比例伯德图坐标纸省去手动调整坐标轴的繁琐步骤。配合说明文档读者可快速掌握传递函数频率响应绘制方法并将成果保存为PNG或PDF用于论文插图、实验报告与工程分析有效提升控制系统设计的效率与规范性。1. 伯德图不是「画出来」就完事bode() 默认图离打印要求差几步自动控制原理这门课伯德图是绕不开的硬通货。很多人在 MATLAB 里敲一句 bode(G) 就以为完事了结果截图交上去线宽细得像头发丝相位曲线还在 -180° 附近反复横跳根本没法看。这份 Bode_PrintPaper 资源包解决的就是这个 gap把「能运行的 Bode 图」变成「能打印的 Bode 图」。包里是成套的 MATLAB 绘图脚本从传递函数建模、频率响应取数到手写绘图模板、批量导出高分辨率图片每个环节都给了可直接抄的参数。适合做自控课程设计的学生也适合要验证系统稳定裕度的工程师——只敲 bode(G) 然后截图的这份资源是后悔药。2. 建模与取数bode() 背后的频率响应数据怎么拿2.1 三种建模方式tf、zpk、ss 的选型逻辑要画伯德图先得有系统模型。资源包里的示例系统同时给了三种建模方式目的不是炫技而是让你在不同的场景入口都能接上这套绘图流程。先看第一种。% 方式一有理分式传递函数分子分母按 s 降幂排列 G1 tf(10, [1 2 10]);tf 的第一个参数是分子系数 [10]代表常数增益 10第二个参数是分母系数 [1 2 10]对应 s^2 2s 10。系数顺序必须是 s 次数从高到低写反了系统就变成另一个东西画出来的伯德图会和手算完全对不上。这个坑我在课程设计时踩过一次当时怎么都对不上渐近线最后发现是分母系数写反了。% 方式二零极点增益形式直观体现系统的极点分布 G2 zpk([], [-13j, -1-3j], 10);zpk 的三个参数分别是零点、极点、增益。这个例子没有零点极点在 -1±3j是一对共轭复极点自然频率约 3.16 rad/s阻尼比约 0.316。用 zpk 建模的好处是能从极点位置直接预判谐振峰出现的频段画完图可以拿这个预期去验证曲线形状。% 方式三状态空间模型适合 MIMO 或从 Simulink 导出的系统 A [0 1; -10 -2]; B [0; 1]; C [10 0]; D 0; G3 ss(A, B, C, D);ss 建模适合状态方程已经摆在面前的情况比如从 Simulink 线性化分析导出的模型或者需要同时看多个输入输出通道的 MIMO 系统。三种方式最终画出来的伯德图完全一致因为 MATLAB 内部都会先算频率响应再绘图。我刚拿到资源包时不太信把 G1、G2、G3 用三种不同线型画在同一个 figure 里三条曲线严丝合缝这才确认 tf、zpk、ss 三种入口在频率响应计算上是完全等价的。选型一句话手推的传递函数用 tf零极点明确的用 zpk状态方程现成的用 ss。2.2 取数mag、phase、w 的数据结构资源包的主脚本几乎不用 bode(G) 直接画图而是用带返回值的调用方式把数据取出来自己排布。原因很简单默认图的排版离打印要求太远自绘才有控制权。% 取出频率响应数据w 是频率向量mag 是线性幅值phase 是相角 [mag, phase, w] bode(G1); % 幅值转 dB去掉单例维度 mag_db 20 * log10(squeeze(mag)); phase_deg squeeze(phase);这里有个新手必踩的坑SISO 系统下 mag 和 phase 返回的是 1×1×N 的三维数组。直接 plot(w, mag) 会得到一堆空线因为 MATLAB 不知道你想画哪个维度。squeeze 把长度为 1 的维度压缩掉得到 N×1 向量之后才能和 w 对齐。另一个细节是 phase 返回的单位是度deg不是弧度后面要做解包裹时必须先用 pi/180 换算否则结果完全不对。幅值为什么要转 dB因为幅频特性跨越好几个数量级线性坐标下曲线全挤在一起看不出渐近线斜率。20*log10 是幅值转分贝的标准公式也是手画伯德图纵轴的单位。2.3 频率范围与点数logspace 的参数怎么定bode() 不指定频率时会自动扫描一个足够宽的频带。但资源包里的脚本都显式指定频率范围原因有两个让曲线覆盖你关心的频段让数据点分布可控。% 频率范围 0.01 到 1000 rad/s对数等间距 500 个点 w logspace(-2, 3, 500); [mag, phase, ~] bode(G1, w);logspace 的 -2 和 3 分别代表 10^-2 到 10^3即 0.01 到 1000 rad/s。低频从 0.01 起步是为了让积分环节的低频渐近线有至少两个十倍频程的展示空间高频到 1000覆盖穿越频率附近的关键区域。500 个点对打印分辨率没有影响但对相位曲线在谐振点附近的平滑度很关键——点太少转折频率附近会出现折线感。注意logspace 的第三个参数是总点数不是密度。相同频段跨度下点数翻倍相邻点的频率间隔才会减半。如果发现相位曲线在谐振峰附近有明显尖角先把点数加到 800 试试这个玄学问题多半是点数不够引起的而不是绘图模板的问题。2.4 用三类典型环节验证曲线形状画完图先别急着导出用典型环节的预期形状自检一遍能拦住大部分数据错误。任何传递函数都可以拆成增益、积分/微分环节、一阶惯性环节和二阶振荡环节的组合。纯增益 K整条幅频曲线抬高 20*log10(K) dB相位不变。积分环节 1/s幅频斜率 -20 dB/dec在 ω 1 处过 0 dB。一阶惯性 1/(Ts1)转折频率 ω 1/T之后斜率变为 -20 dB/dec转折点处幅值比渐近线低 3 dB。% 用一阶惯性环节验证取数流程是否正确 G_check tf(1, [1 1]); % 转折频率 1 rad/s [mag_check, ~, ~] bode(G_check, 1); mag_check_db 20 * log10(mag_check); % 理论上应为 -3.01 dB误差在数值计算精度内这一段的自检逻辑如果 mag_check_db 明显偏离 -3.01 dB说明 squeeze 或 log10 的处理有问题先修数据管线别急着调图。3. 手绘模板线宽、字体、网格这些打印细节为什么不能省3.1 默认 bode() 图的三个硬伤拿 bode(G) 直接出的图去打印通常有三个问题。第一线宽默认只有 0.5 pt喷墨打印出来像头发丝论文里缩印之后直接看不清。第二没有网格线也没有单位标注幅频纵轴只写 Magnitude读者不知道是 dB 还是线性值。第三标题、图例的字体和排版都是默认值中文字体还经常乱码。如果你用 bodeplot 而不是 bode能直接设置 LineStyle、LineWidth 这些属性免去手绘的麻烦。但 bodeplot 的输出仍是固定布局相位解包裹、中文字体、批量导出这些需求它管不了所以我更倾向于 semilogx 全手绘。这三个问题都不影响 bode() 的计算结果但直接影响图能不能用资源包的做法就是彻底绕开自动绘图。3.2 幅频与相频分栏绘图模板代码两行子图是最常用的布局上半幅频、下半相频共用横轴。以下模板可以直接抄。% 画布尺寸设为厘米单位宽 16 cm、高 12 cm适合双栏论文排版 figure(Units, centimeters, Position, [2 2 16 12]); % 上半幅频特性 subplot(2, 1, 1); semilogx(w, mag_db, LineWidth, 1.2, Color, [0.10 0.40 0.80]); hold on; grid on; grid minor; ylabel(幅值 (dB)); title(开环系统的伯德图); set(gca, FontName, Times New Roman, FontSize, 10.5); % 下半相频特性 subplot(2, 1, 2); semilogx(w, phase_deg, LineWidth, 1.2, Color, [0.80 0.20 0.20]); hold on; yline(-180, k--); % -180° 参考线判断稳定性用 grid on; grid minor; ylabel(相角 (deg)); xlabel(频率 (rad/s)); set(gca, FontName, Times New Roman, FontSize, 10.5);参数说明逐个说。LineWidth 1.2 是打印的推荐值低于 1.0 导出后容易发虚超过 1.5 又显得粗糙。Color 用 RGB 三元组而不是简写 b 和 r因为简写颜色打印出来偏艳三元组可以调成接近印刷色。grid minor 开启次要网格在对数坐标下每个十倍频程内再细分方便读渐近线斜率。yline(-180, k--) 是相频图上的稳定性参考线——判断系统是否稳定的关键就是从这条线读相位裕度。FontName 设成 Times New Roman 是英文排版的安全选择但注意它不支持中文。如果你的标签里有中文要么改成英文要么单独设中文字体后面避坑章会细说。figure 的 Position 四项分别是屏幕起点 x、y 和宽、高单位跟随 Units这里设成厘米是为了和后续打印纸张尺寸对齐。3.3 多曲线对比线型与图例的约定控制课设里最常见的需求是校正前后的对比。两条线叠在一张图上时线型和颜色都要有区分度还得考虑打印出来是黑白的。% 叠加显示校正前后的幅频特性 h1 semilogx(w, mag_db_before, b-, LineWidth, 1.2); hold on; h2 semilogx(w, mag_db_after, r--, LineWidth, 1.2); legend([h1 h2], {校正前, 校正后}, Location, southwest);实线和虚线搭配比两条同线型不同颜色的方案更稳妥黑白打印也能区分。legend 的 Location 选 southwest 或 northeast避免盖住曲线穿越 0 dB 的位置。这里用句柄数组 [h1 h2] 而不是让 legend 自动抓取是因为自动抓取经常把网格或参考线也算进去导致图例顺序错乱这在叠加了 yline 之后尤其明显。3.4 坐标轴细节对数刻度与刻度标签semilogx 已经处理了对数横轴但有两个细节容易翻车。第一如果误用 plot(w, mag_db)横轴变成线性刻度低频段全部挤在左边整个图看起来像一条竖线。第二X 轴刻度标签默认科学计数法打印出来是 10^-1、10^0 这种形式可读性还行但如果想要 0.1、1、10 这种普通数字需要手动指定。% 手动指定横轴刻度0.01, 0.1, 1, 10, 100, 1000 set(gca, XTick, [0.01 0.1 1 10 100 1000]); set(gca, XTickLabel, {0.01, 0.1, 1, 10, 100, 1000});XTick 和 XTickLabel 必须一一对应个数不一致会直接报错。这个设置通常在数据量大的图上用数据点少时默认的刻度已经够清楚设了反而显得啰嗦。4. 批量出图与打印尺寸exportgraphics 的高分辨率导出路径4.1 三种导出方式怎么选MATLAB 出图有三个主流选择我按自己的使用经验排一下优先级。方式语法分辨率适用场景exportgraphicsexportgraphics(gcf, a.png, Resolution, 300)可控最高 600R2020a 之后的推荐方式自动裁剪白边printprint(gcf, -dpng, -r300, a.png)可控老版本兼容性好paper 参数相关的坑多saveassaveas(gcf, a.png)固定 96 dpi只适合截图留念不适合打印saveas 固定低分辨率拿去打印会糊。print 是老牌方案但在输出尺寸上有很多 PaperPosition 相关参数要调漏一个就翻车。exportgraphics 在 R2020a 之后可用自动裁剪画布周围的白边省去手动设置 PaperPosition 的麻烦是我现在的主力导出方式。% 推荐exportgraphics300 dpi 满足打印最低要求 exportgraphics(gcf, bode_G1.png, Resolution, 300);Resolution 参数直接控制输出像素密度。300 dpi 是打印的最低标准投期刊图建议 600。注意 exportgraphics 裁剪的是图形对象本身的外接区域如果你用默认的 subplot 布局它会把整个 figure 包括标题栏一起裁进去所以 figure 的 Position 要先设好。4.2 打印纸张尺寸与图面比例如果你要把图排进 Word 或 LaTeX图的长宽比和绝对尺寸就得提前想好。双栏论文的单栏图片宽度一般 8-9 cm通栏图 16-17 cm。资源包里的模板默认 16×12 cm 的 figure对应通栏宽度两行子图各占一半高度。% 控制打印纸张和版心单位统一为厘米 set(gcf, PaperUnits, centimeters); set(gcf, PaperSize, [16 12]); set(gcf, PaperPosition, [0 0 16 12]);PaperUnits 设成 centimeters 是为了让 PaperSize 和 PaperPosition 的单位一致。这三个 set 连用是 print 和 PDF 导出的标准前置操作能避免「屏幕上正常、存成 PDF 后图被裁掉一半」的经典翻车。如果你只用 exportgraphics前两个 set 可以省略但 PaperPosition 设一下没坏处。导出矢量图也是论文场景的常见需求。矢量图在 PDF 里任意缩放都不失真适合 LaTeX 用户。% 矢量格式导出PDF 或 SVG exportgraphics(gcf, bode_G1.pdf, ContentType, vector); exportgraphics(gcf, bode_G1.svg, ContentType, vector);ContentType 设为 vector 时导出的是矢量图形而不是位图。注意矢量图对字体的要求更高如果系统缺了模板里指定的字体PDF 里会变成乱码或替换字体。4.3 批量处理多个系统的循环脚本资源包里最实用的部分我认为是批量导出脚本。控制课设往往要画七八个系统的伯德图手动一个个导又慢又容易漏。% 批量绘制并导出多个系统的伯德图 systems {G1, G2, G3}; sys_names {G1_simple, G2_zpk, G3_ss}; for i 1:length(systems) % 统一使用同一频率向量保证图与图可比 [mag, phase, ~] bode(systems{i}, w); mag_db 20 * log10(squeeze(mag)); phase_deg squeeze(phase); figure(Units, centimeters, Position, [2 2 16 12]); subplot(2, 1, 1); semilogx(w, mag_db, LineWidth, 1.2); grid on; ylabel(幅值 (dB)); title([开环伯德图 - sys_names{i}]); subplot(2, 1, 2); semilogx(w, phase_deg, LineWidth, 1.2); grid on; ylabel(相角 (deg)); xlabel(频率 (rad/s)); % 统一 300 dpi 导出文件名带系统标识 exportgraphics(gcf, [bode_ sys_names{i} .png], Resolution, 300); close(gcf); % 关掉当前 figure防止循环里内存堆积 endclose(gcf) 是循环里最容易被漏掉的一行。如果循环体最后不关 figure每一轮都会开一个新窗口跑完七八个系统后内存占用会涨得很快老机器甚至会卡死。sys_names 里我加了后缀区分建模方式导出文件名一目了然后续整理报告时不会搞混。这段脚本的另一个细节是统一 w 向量。所有系统用同一组频率点导出的图才有可比性画在同一张图里叠加时完全对齐。如果每个系统用默认频率范围频率点分布不一致叠加时曲线在细节上会错位。提示如果系统里含 time delay 或复杂的非最小相位环节直接用 bode 自动选频可能漏掉关键频段建议在循环里显式传入 w 并扩大范围。5. 避坑相位跳变、NaN 与图例错位的五个排查记录5.1 相位曲线在 ±180° 附近跳变现象相位曲线在 -180° 附近突然从 -179° 跳到 179°或反过来图上出现一个突兀的尖刺相频曲线看起来像断裂了。原因MATLAB 默认把相角包裹在 (-180°, 180°] 区间内。系统相位越过 -180° 时会直接从 -180° 跳到 180°实际上相位是连续的但显示出来就是跳变。对于含积分环节的系统相频曲线经常跨过 ±180°所以这个现象非常常见。解决对相位做 unwrap 解包裹。MATLAB 的 unwrap 函数会把相邻点的跳变补齐还原连续相位曲线。% 相位解包裹输入弧度输出也是弧度 phase_unwrapped unwrap(phase_deg * pi / 180) * 180 / pi;注意 unwrap 要求输入是弧度所以要先把 deg 转成 rad处理完再转回 deg。unwrap 默认的跳变阈值是 π如果你的相位数据恰好只有很小的跳变比如噪声引起的此时不会触发修正要回头检查原始数据而不是怪 unwrap。5.2 低频段幅值为 NaN 或 -Inf现象画幅频图时曲线低频端突然断掉或者出现一个指向 -∞ 的尖峰整条曲线的形状完全不符合渐近线预期。原因系统含积分环节 1/s 时s 0 处增益无穷大。如果 w 向量里包含 0或者频率下限取得太低20*log10 计算时会得到 Inf 或 NaN。低频渐近线是 -20 dB/dec 的斜线频率越低幅值越大这是正常的但数据点算不出来就是程序问题。解决频率下限从 1e-2 起步别把 w 写成从 0 开始的等差序列。用 linspace(0, 100, 1000) 这种写法画伯德图是必然翻车的横轴必须用 logspace 或对数刻度。% 错误示范w 包含 0低频端出 NaN w_bad linspace(0, 100, 1000); % 正确做法w 从 1e-2 开始对数等间距 w_good logspace(-2, 2, 500);5.3 叠加两条曲线后图例对不上现象用了 hold on 在同一个坐标区画两条曲线legend 里传了两个字符串但显示出来的线型和图上对不上或者图例多出一些莫名其妙的项。原因legend 在没指定句柄时按坐标区里图形对象的创建顺序自动抓取。如果之间插入了 yline、grid minor 生成的线对象或者先画了别的辅助线自动抓取就会错位图例项数量和线型全乱。解决返回 semilogx 的句柄用句柄数组显式指定图例项。h1 semilogx(w, mag_db_before, b-, LineWidth, 1.2); hold on; h2 semilogx(w, mag_db_after, r--, LineWidth, 1.2); legend([h1 h2], {校正前, 校正后}, Location, southwest);这个习惯我后来一直保留只要一个坐标区里的线超过一条就一律用句柄指定图例省得后面加辅助线时图例变乱。5.4 中文标签导出后变方块现象标题用中文屏幕上显示正常用 exportgraphics 导出 PNG 后中文全变成方框或乱码打印出来更是没法看。原因模板里 FontName 设的是 Times New Roman这个字体不含中文字形MATLAB 在导出时会用系统默认中文字体替换替换失败就渲染成方块。另一个相关问题是字体嵌入导出 PDF 时如果字体没嵌入换台电脑打开就缺字。解决两条路。要么图内文字全部用英文这是论文投稿最稳的做法要么在 Windows 下把字体设成 SimHei 或 Microsoft YaHei。% 中文字体设置WindowsSimHei 打印黑体效果 set(gca, FontName, SimHei); % 标题单独设字体正文和刻度保持 Times New Roman title(开环系统的伯德图, FontName, SimHei);提示投稿论文时图内文字建议全部使用英文中文字体在不同平台和不同 PDF 阅读器下的渲染差异太大省事也省心。5.5 subplot 标题与刻度标签重叠现象两行子图之间上面的标题和下面子图的刻度标签贴在一起导出的图里文字互相压着分辨率越高越明显。原因figure 高度不够或者字号调大后 subplot 默认间距不足。默认的 subplot 间距是按默认字号算的字号调到 10.5 甚至 12 后间距就不够用了。解决把 figure 高度从 12 加到 14 厘米或者用 subplot 的 Position 属性手动布局。% 手动布局两行子图分别指定位置单位是归一化坐标 subplot(Position, [0.12 0.55 0.82 0.38]); subplot(Position, [0.12 0.12 0.82 0.38]);用归一化坐标的好处是精确控制间距和留白缺点是换字体或字号时还要回来重新调。偷懒方案是把 figure 高度加大到 14大多数情况下够用。6. 进阶用 margin() 数据交叉验证手绘图上的裕度标注手绘图再漂亮数据错了也是白搭。最后这步是把 margin() 的系统计算结果和你手绘的曲线做交叉验证确保图上的每个关键点都能对上数字。6.1 margin() 的四个返回值[Gm, Pm, Wcg, Wcp] margin(G1);Gm 是幅值裕度返回值是线性值转 dB 要 20*log10(Gm)Pm 是相角裕度单位 degWcg 是相位穿越频率即相位等于 -180° 的频率Wcp 是增益穿越频率即幅值等于 0 dB 的频率。这四个值是自控课设里稳定分析的输出结果现在反过来用它们验证绘图。6.2 在自绘图上标注穿越频率% 幅频图上加 0 dB 参考线和增益穿越频率标记 figure(Units, centimeters, Position, [2 2 16 12]); subplot(2, 1, 1); semilogx(w, mag_db, LineWidth, 1.2); hold on; yline(0, k-); semilogx([Wcp Wcp], ylim, k--); text(Wcp, -20, sprintf(ω_c %.2f rad/s, Wcp), FontSize, 9);ylim 取当前坐标区纵轴范围semilogx 画竖线时要用它不然线段长度不对。text 的位置要避开曲线本身幅频图上 Wcp 处曲线必定穿过 0 dB所以把文字放在 -20 dB 附近不会挡线。6.3 三个验证步骤第一步看幅频曲线穿过 0 dB 的横坐标和 Wcp 对比误差应在几个点以内。第二步在 Wcp 处的相频曲线上读相角值Pm 相角值 180°和 margin 返回的 Pm 对比。第三步在 Wcg 处读幅值20*log10(Gm) 应该等于该处幅值的绝对值因为幅值裕度本质是 0 dB 减去 Wcg 处的幅值。三个验证做完这张图就不是「看着像那么回事」而是每个关键点都有据可查。从那以后我每次画完伯德图都强制自己走一遍这步线宽、字体、导出参数全部按资源包里的模板来不自己临时乱调。磨刀不误砍柴工这套流程跑顺了画一张图从建模到导出用不了两分钟希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询