Simulink PowerGUI FFT数据导出Origin频谱图重绘方法详解

发布时间:2026/10/10 19:10:38

Simulink PowerGUI FFT数据导出Origin频谱图重绘方法详解 搞Simulink仿真的人应该都有过这种经历模型跑完打开PowerGUI的FFT Analysis窗口鼠标点几下看到一屏幕漂亮的谐波柱状图和列表然后面对两个选择——截图裁剪进论文或者对着屏幕把几十个频率点的幅值和相位抄进Excel。截图分辨率有限手动抄数容易看错行论文返修时明明只改了一个仿真参数整套谐波分析图又得重新和Origin里的图对一遍这一来一回至少折腾半天。我自己最初也是截图党后来被导师和审稿人来回折腾几次实在撑不住就专门花时间研究了一套从Simulink PowerGUI的FFT分析结果导出数据、再到Origin里重绘的工作流。这套方法不需要额外安装任何工具箱只要有一台装了MATLAB/Simulink和Origin的电脑跟着下面的步骤走就能把PowerGUI窗口里显示的幅值、相位、频率数据原样搬进Origin绘图结果和PowerGUI显示的一致程度可以做到逐位核对不差。文末的MATLAB源码我放在对应小节里复制就能用。这个方案适合三类人写论文需要放谐波频谱图的工科研究生做电能质量分析需要输出规范报告的工程师以及被审稿人要求“把仿真图重新画清楚一点”的科研党。下面从需求拆解开始说。1. 需求拆解PowerGUI能显示什么你又想导出什么1.1 PowerGUI FFT分析窗口的显示逻辑PowerGUI在Simulink的Simscape Electrical体系里用得很多。模型里放一个PowerGUI模块双击打开切到FFT Analysis标签就能看到对某个测量信号的频谱分析结果。窗口里主要有几个参数区Signal Selection区域选择一个X Axis Measurement某个Scope信号或To Workspace变量FFT settings区域设置Fundamental frequency基波频率、Max frequency最大频率、Max frequency for THD computationTHD计算频率上限、Number of cycles分析周期数。显示结果有两种形式上方的频谱图以及下方的表格表格里有频率、幅值、相位三列。多数人不清楚的是PowerGUI的FFT结果完全来自于工作区里的仿真波形数据。它会把数据按用户设置的周期数截取一段执行离散傅里叶变换再整理成单边频谱显示。它不会单独保存这些谱数据也没有直接导出一张结构化表格的便捷按钮所以数据复用能力很差。这个界面设计考虑的是“看一眼”而不是“拿数据走”。但科研出图恰恰要拿数据走。我最早尝试过对着List结果逐个抄抄到THD计算需要把各次谐波加起来的时候错一个数字整张表就得重来。所以第一步要解决的核心问题就是让FFT数据从PowerGUI界面背后出来并且以结构化、能够被Origin直接识别的形式存在。1.2 需要导出的字段拆解在动手写脚本前先把目标理清楚。通常我们需要导出的内容分两类。第一类是频谱明细数据格式大致是谐波次数Order1、2、3……直到需要的最高次频率Hz基波频率的整数倍幅值PowerGUI默认显示的是相对基波的百分比也支持绝对值相位deg每个谐波对应的初相角。第二类是汇总指标主要是THD总谐波失真率、基波幅值、各相之间的相位差。THD在论文里经常要单独列一张表。在Origin里画频谱图常见呈现方式有两种柱状图x轴是谐波次数或频率y轴是幅值百分比线图显示频域的连续谱线。无论哪种方式只要拿到上面那张明细表都能用Origin的模板快速画出来。所以问题的核心落到两步获取数据转换格式。2. 技术路线选型三条路我推荐第二条2.1 三条可行路线对比我认真评估过三种从PowerGUI拿数据的方案各有取舍。方案A是界面手动操作。在PowerGUI窗口里手动点取或者直接截图后用工具提取数据。缺点是PowerGUI窗口导出的内容在不同版本里深浅不一多数情况下只能导出当前显示的图片不包含数据表截图提取精度就更没保证了。方案B是利用工作区数据在MATLAB脚本里自己按PowerGUI的算法执行FFT计算得到相同结果后再导出到Excel或文本最后导入Origin。这条路线可控性强不依赖PowerGUI版本界面的变化结果可以逐项验证也容易批量处理多组工况。方案C是直接调用Simscape Electrical内部API去读PowerGUI的分析结果。部分MATLAB版本存在power_fft这类底层函数但跨版本兼容性很差文档也不全。我试过在R2020b上能用换到R2023a的机器就找不到对应函数了对多数人来说不实用。权衡后我采用方案B不硬啃PowerGUI内部函数而是基于一个事实——PowerGUI的FFT结果本质就是“针对同一段仿真波形、按用户设置的周期数与频率范围执行的单边FFT计算”。脚本里完整复算一遍整理成结构化表格。只要参数设置一致、数据来源一致结果与PowerGUI窗口显示的数值在浮点误差范围内完全相同。这一点后面有对照验证的说明。2.2 整体数据链路设计整体思路很朴素Simulink模型 - 记录目标信号到工作区 - MATLAB脚本读取信号并执行FFT计算 - 输出Excel或文本文件 - Origin导入并绘图。这个链路里有一个关键设计点信号记录必须稳定。在Simulink里推荐两种做法在目标支路电网电压、逆变器输出电流、电机绕组电流接入To Workspace模块输出格式设为Structure With Time仿真结束后变量留在工作区。在Scope模块里勾选Log data to workspace把Scope的信号输出到ScopeData结构体变量。采样时间的设置要根据FFT需要覆盖的最高频率来确定。比如要分析到50次谐波频率上限2500Hz采样频率至少不低于5000Hz考虑到工程余量通常设到几十kHz量级问题不大。简单说就是奈奎斯特采样定理的工程实践。脚本内部做的事情概括成四步从工作区变量中取出时间向量和信号向量。按照PowerGUI的参数计算参与FFT的采样点数NN等于周期数乘以基波周期内的采样点数。对截取的数据做FFT计算并按单边谱规则转换幅值乘以2、排除镜像频率。在设定的频率范围内逐次提取基波与谐波的幅值和相位写成表格。实际项目里我通常把多组仿真结果全部循环导出Origin里一次性导入多张表画成对比图效率提升非常明显。3. MATLAB源码实现完整复算PowerGUI的FFT结果3.1 PowerGUI的FFT算法本质先说明为什么自己可以复算。根据MATLAB文档和多次比对经验PowerGUI的FFT分析执行的是标准的单边离散傅里叶变换步骤为对截断的时域序列 x(n)n0,1,...,N-1做FFT得到复数序列X(k)。幅值谱归一化X_mag(k) |X(k)| / N。单边化处理除k0直流分量和kN/2奈奎斯特频率点仅当N为偶数时存在外其余频率点的幅值乘以2。频率轴f(k) k × fs / N。相位谱angle(X(k))转换为度并做±180°范围内的归一化。PowerGUI计算THD时默认以基波幅值为基准表达式为THD sqrt(sum(谐波幅值^2)) / 基波幅值 × 100%。只统计设定频率范围内的谐波不计直流分量。这些细节写在MATLAB官方文档和Simscape Electrical的源代码注释里。只要读一遍整个过程就透明了。理解了原理“一模一样”就不再依赖黑盒我们只管把参数对齐跑完验证即可。3.2 核心源码从工作区提取并计算FFT结果下面这个函数是我一直用的省去PowerGUI界面的手动操作同时保证计算结果一致。代码基于MATLAB R2020b之后的版本验证更早版本可能存在函数替换问题。function fftTable exportPowerGuiFFT(variableName, fBase, fMax, numCycles) % exportPowerGuiFFT 复现PowerGUI FFT分析结果 % 输入 % variableName : Simulink导出的工作区结构体变量名 % fBase : 基波频率如 50 或 60 % fMax : 最大分析频率如 2500 % numCycles : 参与FFT分析的周期数如 3 或 5 % 输出 % fftTable : 表格列依次为 谐波次数/频率/幅值绝对值/幅值百分比/相位(deg) % 读取工作区结构体 if ~evalin(base, sprintf(exist(%s, var), variableName)) error(工作区中不存在变量%s, variableName); end data evalin(base, variableName); % 兼容数据格式Structure With Time if ~isstruct(data) || ~isfield(data, time) || ~isfield(data, signals) error(请使用Structure With Time格式记录信号); end t data.time(:).; x data.signals.values(:).; % 基础参数 fs 1 / (t(2) - t(1)); % 采样频率 if fMax fs / 2 error(fMax超过奈奎斯特频率fs/2 %.2f Hz, fs/2); end N round(numCycles * fs / fBase); % 参与FFT的采样点数 % 截取指定周期数的数据段 if length(x) N error(数据长度不足需要 %d 个采样点当前仅 %d 点, N, length(x)); end xSeg x(1:N); % FFT计算 X fft(xSeg); XMag abs(X) / N; XPhase angle(X); % 单边谱修正除直流和奈奎斯特点外幅值翻倍 XMag(2:end-1) XMag(2:end-1) * 2; % 频率轴 freq (0:N-1) * fs / N; % 定位基波峰值作为基准 fdIdx find(freq fBase*0.9 freq fBase*1.1); [baseMag, ~] max(XMag(fdIdx)); % 逐次提取谐波 orderMax floor(fMax / fBase); results zeros(orderMax, 5); for k 1:orderMax fTarget k * fBase; [~, idx] min(abs(freq - fTarget)); magAbs XMag(idx); magPercent magAbs / baseMag * 100; phaseDeg XPhase(idx) * 180 / pi; if phaseDeg 180 phaseDeg phaseDeg - 360; end results(k, :) [k, fTarget, magAbs, magPercent, phaseDeg]; end % 构建表格输出 fftTable array2table(results, ... VariableNames, {Order, Freq_Hz, Mag_Abs, Mag_Percent, Phase_deg}); end有几个值得说明的地方。第一幅值相对基波的百分比计算。我先在基波附近频率窗口内找峰值作为基准而不是直接用第1次谐波的索引这样可以抵消频率分辨率不足时栅栏效应带来的微小偏差。实测这个做法和PowerGUI的显示误差可以控制在0.01%以内。第二相位角度处理。PowerGUI的FFT窗口显示-180°到180°范围MATLAB的angle函数默认返回-π到π转成角度后正好是这个范围。代码里做了一次归一化把大于180°的值减360°。如果你习惯用0°到360°改成phaseDeg mod(phaseDeg, 360)即可。第三频率点索引。PowerGUI取的是谱线中离目标频率最近的频点所以我用min(abs(freq - fTarget))来找。当N恰好是fs/fBase的整数倍时这个最近频点就是精确的k×fBase万一采样率不是整数倍也能取到最接近的一条谱线脚本不会落空。3.3 调用示例与PowerGUI对照验证实际项目里我这么配置。假设模型里有一个三相逆变器要分析A相并网电流的谐波。用To Workspace模块Variable name设为ia_measure输出格式选择Structure With Time采样时间设成1e-5对应100kHz采样率仿真时长跑完若干个工频周期。仿真结束、数据落进工作区后命令行执行res exportPowerGuiFFT(ia_measure, 50, 2500, 5); disp(res);得到的结果类似这样OrderFreq_HzMag_AbsMag_PercentPhase_deg15012.31100.00-12.3521000.0120.1078.2131500.8216.67165.4252500.6124.97-88.63把这个结果和PowerGUI窗口里显示的数值逐一对比谐波次数、幅值百分比、相位都能对上。这就是“一模一样”的验证思路不是靠信任而是靠逐项核对。核对时的实操细节在PowerGUI窗口里把Display style设置为ListFrequency axis设为LinearMax frequency设为2500Cycles设为5。建议在建模初期就固定这套参数后面对比时省心很多。我在项目里会把脚本与模型参数写在同一个说明文档里防止不同批次仿真之间参数漂移。4. Origin导入与“一模一样”绘图实操4.1 数据导出文件格式与列布局设计计算完成后离Origin只差一个文件。我习惯直接写Excel表格因为Origin对Excel的导入兼容性最好。导出代码很简单fname sprintf(FFT_Result_%s.xlsx, date); writetable(res, fname, Sheet, 1);如果更习惯文本文件也可以用writematrix(res{:,:}, fft.txt, Delimiter, tab)。Origin同样支持带制表符分隔的txt直接拖入。优先选Excel的原因在于Origin导入Excel时可以保留列标题行和列数据类型后续模板映射更稳。导出的Excel列顺序建议固定为谐波次数Order、频率Hz、幅值绝对值A或V、幅值相对基波百分比%、相位deg。这个顺序与PowerGUI窗口显示顺序一致在Origin里选列也方便。多组数据对比时我在文件名的后缀里标注工况比如FFT_Result_nominal.xlsx、FFT_Result_overload.xlsx。Origin导入后工作表名自带信息图例标注直接引用工作表名省去手动改名的时间。4.2 Origin导入三步接住数据在Origin里新建工程操作分三步。第一步把Excel文件直接拖进Origin左侧面板或者用菜单File - Import - Excel快捷键CtrlShiftX。导入时会出现Import Wizard关键设置项有两个保持默认的Import as为Workbook Sheet让Excel里的Sheet1变成Origin里的工作表。勾选Column labels选项让第一行列标题被识别为Long Name而不是数据行。第二步选中列数据Order、Freq_Hz、Mag_Percent、Phase_deg用Plot - Column/Bar/Pie里的Column画柱状图。大多数频谱图用柱状图x轴用Order或Freq_Hz都可以。如果要把幅值和相位分开画两张图改动x轴列重新绘图即可模板可以共用。第三步微调坐标轴。双击坐标轴打开Axis对话框在Scale选项卡里把X轴范围设为0或1到orderMax0.5Major Ticks间隔设成1这样每条谐波一根柱Y轴范围根据幅值最大值留出10%余量。这样图表结构和PowerGUI窗口里“每条谐波一根柱、间距均匀”的样子非常接近。页面尺寸按目标期刊或论文的插入栏宽设置单栏图宽8.8cm双栏图宽17.8cm。字体统一用Arial或Times坐标轴标题字号9到10pt。这些设置保存成模板后下一组数据直接套用五分钟出一张图。4.3 如何做到视觉层面的高度还原很多用户说想要“一模一样”的图其实包含两层意思数据一致观感一致。数据一致由脚本保证观感一致取决于Origin里的重绘样式。PowerGUI的FFT窗口默认样式是x轴为线性频率刻度范围0到Max frequencyy轴为幅值百分比或绝对值柱状图柱宽适中颜色单一表格可同时显示频率、幅值、相位。在Origin里复刻时我的默认做法是柱状图填充颜色选自定义RGB比如深蓝色RGB 0, 70, 150印刷清晰。柱宽设置为可用空间的80%双击柱子在Pattern选项卡的Gap Between Bars里设为20。去掉不必要的边框线保持视觉简洁。坐标轴标题写规范X轴写Frequency (Hz)或Harmonic OrderY轴写Magnitude (% of Fundamental)。加一道从0开始的水平浅灰虚线网格方便读值。THD这类汇总指标可以先算好在Origin图上方用文本工具标注例如THD 3.42%。插入文本用快捷键CtrlT手动输入内容后拖到目标位置。有一点提醒PowerGUI窗口的背景色不需要模仿。论文最终都是白底黑字以目标期刊的排版要求为准黑色文字和标准框线是最稳妥的。5. 常见问题与排查技巧实录5.1 计算出的幅值和PowerGUI对不上这个问题最容易出现多数情况是参数没对齐尤其是采样率太低、周期数取得不够、截取的数据段长度不一致。我的排查顺序是固定的检查脚本里使用的周期数与PowerGUI窗口的Number of cycles是否相同。检查采样时间是否为定步长。如果用了变步长求解器Scope记录的采样点间隔不均FFT结果就会和PowerGUI有细微差异。解决办法是给To Workspace模块的采样时间设成固定值同时把求解器的最大步长上限也设成同一值。检查数据起始点是否对齐。PowerGUI默认截取信号时间起点到指定周期数长度的段落如果Scope记录从仿真0时刻开始两者一致。如果使用了延迟或事件触发需要先用脚本对齐时间起点。5.2 相位显示范围不一致PowerGUI的相位显示在部分版本里用0°到360°范围有的用-180°到180°。如果结果与界面显示的相位在数值上相差180°说明相位范围转换没对齐。可以在脚本里把phaseDeg统一成0°到360°或者用mod直接转换。比较时注意两个版本的趋势一致就好。我自己的习惯是固定用-180°到180°因为电气工程论文里这个范围用得最多。5.3 Origin导入后列名变成系统默认Excel导入时偶尔会碰到Origin把Excel的第一行当成普通数据导致列名变成A、B、C、D。这通常是导入向导的Column Labels勾选漏掉了。正确做法是在Import Wizard第一步勾选Column Labels并确认Long Name来自Excel的第一行。如果已经导错撤销重导即可不用手工改列名。5.4 多组数据对比时图例混乱做多个工况对比时建议不要在同一工作表里追加数据列而是在Origin里分别导入每个Excel文件到独立工作表然后用Layer Contents把每个数据集的柱状图叠加到一个图里。具体做法先画出第一组柱状图然后用Graph菜单下的Layer Contents向当前图层追加第二组、第三组的Y列。这样可以单独控制每个数据集的柱宽、颜色与图例名称最终得到整齐的分组柱状图。5.5 栅栏效应导致的幅值偏差当基波频率正好等于频率分辨率fs/N的整数倍时FFT谱线中心会落在基波上计算最准。如果N不是fs/fBase的整数倍基波能量会泄漏到相邻频点导致提取的幅值偏低。修正有两种思路把N取成fs/fBase的整数倍刻意让频谱栅格对齐谐波频率。使用双谱线插值等算法重构真实幅值但这样会偏离PowerGUI的算法不符合“一模一样”的前提。我用的是第一种思路也就是保证N等于numCycles × fs / fBase为整数。脚本里用round修正N然后通过截取数据段对齐最终结果和PowerGUI的误差控制在浮点误差范围。如果你的模型里采样率不是基波频率的整数倍记得先调整采样时间。5.6 数据量大导致Origin卡顿仿真时长很长、采样率又很高时导出的数据行数可能达到几十万行Excel文件会很大Origin导入时也卡。解决办法是导出前在MATLAB里对数据降采样或者只导出0到目标频率范围内的谱线结果反正FFT结果表只有几十行。降采样操作可以用resample函数要注意抗混叠滤波别引入伪造的谐波。6. 完整工作流复盘与几个小建议6.1 一次完整操作的时间预期把整套流程的时间用量化一下给读者一个预期Simulink模型里加To Workspace模块并设置参数10分钟含建模时顺手配置。仿真并确认数据落位仿真时间另计。运行exportPowerGuiFFT脚本并核对数据5分钟。输出Excel1分钟。Origin导入并绘制模板图首次15分钟后续每组2分钟。相比手动抄表动辄半小时还要反复核对这套流程的收益非常可观。我自己的项目里一次要做12组工况的谐波分析脚本跑完大约1分钟Origin批量出图大约15分钟整个工作比之前快了一倍不止。6.2 固定参数规范的重要性一个容易被忽略的点是FFT分析结果与参数强相关。同一段数据取的周期数不同、频率范围不同THD和谐波幅值表格会不一样。所以做对比研究时所有工况一定要共用同一组FFT参数。我的习惯是在脚本开头定义一个参数结构体fftParams.fBase 50; fftParams.fMax 2500; fftParams.numCycles 5;所有调用统一用这个结构体避免不同批次的仿真图之间因为参数漂移导致结果不一致。这个习惯在研究项目中帮我避免过很多次返工。最后再分享一个小玩法如果你希望Origin里画出来的频谱图与PowerGUI截图在排版上几乎一致可以先把PowerGUI窗口里的图用File - Print to Figure导出成图片然后在Origin里插入图片作为背景参考图层数据图叠加绘制。我试过几次用来调整柱宽、坐标范围还挺直观。但最终论文里我只会保留Origin重绘的矢量图因为位图放大后清晰度不行矢量图才是投稿与印刷的正道。
延伸阅读

更多相关文章

2026/10/10 19:10:38

Spring Boot优雅关闭全解析:从kill -9到容器销毁的底层机制

1. 关闭流程的底层机制1.1 从 kill 命令到 Spring 容器销毁的完整链路很多同学对应用关闭的理解停留在“进程死了就完事”的层面,但真实情况远比这复杂。以最常见的kill -9和kill(默认 SIGTERM)为例,这两者在 Spring Boot 应用身上…

2026/10/10 21:10:50

好消息与坏消息:如何建立不被情绪绑架的消息处理机制

1. 好消息与坏消息的真相:先别急着高兴,也别急着崩溃你肯定有过这种时刻:手机一震,屏幕上弹出一条消息,你心跳加速,点开之后要么想唱歌要么想砸手机。但过了一个星期回头看,当初那个让你兴奋得整…

2026/10/10 21:10:50

WorkBuddy FDE 90天路径:从一句话需求到上线App的实战指南

一句话需求丢过来,三周后要看到能装进手机里的东西,这种场景在不少小团队里反复上演。WorkBuddy FDE 这套打法,就是冲着这种"需求模糊、时间紧、人手少"的处境来的。它把从一句话到上线 App 的全过程拆成可执行的阶段,核…

2026/10/10 21:10:50

LL(1)分析法实现IF-ELSE翻译程序:四元式与真假链回填

简介:一份面向编译原理学习者的IF-ELSE条件语句翻译程序设计资料,基于LL(1)预测分析法,完成词法分析、语法分析并输出四元式中间代码。资料以Visual Studio工程形式组织,共17个文件,包含C源码、头文件、工程配置文件&a…

2026/10/10 21:10:50

Vibe Coding实战:用Cursor+SDD+Claude Code建立可控AI开发链路

1. Vibe Coding不是让AI写代码,是在和需求反复博弈先说个大家可能都有的经历:拿到Cursor第一周,感觉很爽,让它生成个函数、写个页面,几乎都是秒出。但两周之后,项目越做越乱,AI生成的代码散落各…

2026/10/10 21:05:50

AnyPS5:跨平台异构硬件通用运行环境的设计与实现

1. 项目缘起与核心定位AnyPS5 这个名字第一次出现在我视野里的时候,我正蹲在一堆拆机件中间,手里攥着一块从旧设备上拆下来的定制主板,琢磨着怎么把它的算力榨干。当时脑子里冒出来的念头很直接:能不能做一个足够通用的软硬件框架…

2026/10/10 7:31:36

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/9 20:15:56

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/8 6:05:44

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

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

2026/10/10 0:04:53

从逻辑门到计算机:数字电路核心原理与全加器搭建实战

如果你拆过一台旧电脑的主板,盯着那些黑乎乎的小芯片看上一会儿,可能会冒出同一个疑问:这堆引脚密集的元件,到底是怎么“变”出那么复杂的应用的?答案并不在某个神秘的部件里,而是在所有芯片内部都在反复使…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑