Simulink仿真数据自动化处理:MATLAB脚本批量生成高清波形图
每次运行完Simulink仿真后,面对工作区里堆积如山的d1、d2、d3...数据集,你是否还在手动一个个点击导出图表?工程师的时间不该浪费在重复操作上。本文将分享一套完整的MATLAB脚本解决方案,实现从数据提取、图表生成到自动保存的全流程自动化,特别适合参数扫描、多工况对比等需要批量处理仿真结果的场景。
1. 构建自动化处理框架
1.1 仿真数据标准化命名
在开始编写脚本前,我们需要确保Simulink仿真数据的存储方式具有可预测性。建议在仿真前对示波器进行统一配置:
% 示波器配置示例 set_param([modelName '/Scope'], 'SaveToWorkspace', 'on',... 'SaveName', 'simData', 'DataFormat', 'StructureWithTime');这种配置会生成结构体数组simData,包含time和signals字段。对于多组仿真,可以采用单元数组存储:
simResults = cell(1,5); % 预分配5次仿真结果的存储空间 for i = 1:5 simOut = sim(modelName); simResults{i} = simOut.get('simData'); end1.2 数据批量提取技巧
MATLAB提供了多种数据访问方式,针对批量处理场景,推荐使用动态字段引用:
% 获取第n次仿真的第m个信号数据 signalData = simResults{n}.signals(m).values; timeVector = simResults{n}.time;对于更复杂的信号结构,可以构建辅助函数:
function data = getSignalByName(simStruct, signalName) idx = find(strcmp({simStruct.signals.label}, signalName)); data = simStruct.signals(idx).values; end2. 专业级图表批量生成
2.1 多图布局与样式预设
创建统一的图表样式模板,确保所有生成的图表保持一致的视觉风格:
function applyPlotStyle(hFig) % 设置默认字体 set(hFig, 'DefaultAxesFontName', 'Times New Roman',... 'DefaultTextFontName', 'Times New Roman'); % 获取所有坐标轴对象 ax = findobj(hFig, 'Type', 'axes'); for i = 1:length(ax) set(ax(i), 'FontSize', 12, 'LineWidth', 1.5,... 'XGrid', 'on', 'YGrid', 'on', 'GridAlpha', 0.3); xlabel(ax(i), 'Time (s)', 'FontWeight', 'bold'); end end2.2 动态子图生成算法
根据信号数量自动计算最优的子图布局:
function [rows, cols] = calcSubplotLayout(numPlots) cols = ceil(sqrt(numPlots)); rows = ceil(numPlots/cols); end应用示例:
% 对单次仿真生成所有信号的子图 signals = simResults{1}.signals; [rows, cols] = calcSubplotLayout(length(signals)); hFig = figure('Position', [100 100 1200 800]); for i = 1:length(signals) subplot(rows, cols, i); plot(simResults{1}.time, signals(i).values); title(signals(i).label, 'Interpreter', 'none'); end applyPlotStyle(hFig);3. 高级输出与自动化保存
3.1 多格式输出配置
支持同时生成多种格式的输出文件,满足不同使用场景:
| 格式 | 适用场景 | 分辨率(dpi) | 推荐设置 |
|---|---|---|---|
| PNG | 快速预览 | 300 | '-r300' |
| 印刷出版 | 600 | '-dpdf' | |
| SVG | 矢量编辑 | 矢量格式 | '-dsvg' |
实现代码:
function savePlotMultiFormat(hFig, baseName) % PNG格式 print(hFig, [baseName '.png'], '-dpng', '-r300'); % PDF格式 print(hFig, [baseName '.pdf'], '-dpdf', '-r600'); % SVG格式 saveas(hFig, [baseName '.svg']); end3.2 智能文件命名系统
根据仿真参数自动生成有意义的文件名:
function fileName = generateFileName(simParams, signalName) paramStr = ''; fields = fieldnames(simParams); for i = 1:length(fields) paramStr = [paramStr '_' fields{i} num2str(simParams.(fields{i}))]; end fileName = ['Plot_' signalName paramStr]; end4. 实战:完整批处理流程
4.1 主处理脚本架构
% 初始化 simCases = loadSimulationCases(); % 加载所有仿真配置 outputDir = 'Results_' datestr(now, 'yyyymmdd_HHMM'); mkdir(outputDir); % 批量处理 for caseIdx = 1:length(simCases) % 加载仿真数据 simData = loadSimulationData(simCases(caseIdx)); % 创建图表 hFig = createStandardFigure(); % 绘制所有信号 for sigIdx = 1:length(simData.signals) % ... 绘制代码 ... end % 应用样式 applyPlotStyle(hFig); % 保存输出 fileName = generateFileName(simCases(caseIdx), 'AllSignals'); savePlotMultiFormat(hFig, fullfile(outputDir, fileName)); % 关闭图形 close(hFig); end4.2 异常处理与日志记录
完善的批处理系统需要包含错误处理机制:
try % 主处理代码 catch ME logError(fullfile(outputDir, 'error_log.txt'), ME); continue; % 跳过当前case继续处理下一个 end日志函数示例:
function logError(logFile, ME) fid = fopen(logFile, 'a'); fprintf(fid, '[%s] Error: %s\n', datestr(now), ME.message); for i = 1:length(ME.stack) fprintf(fid, ' %s (%d)\n', ME.stack(i).name, ME.stack(i).line); end fclose(fid); end在实际项目中,这套系统将仿真结果处理时间从原来的数小时缩短到几分钟。特别是在需要反复调整参数进行对比分析时,只需运行一次脚本就能获得所有工况的标准化图表输出。