告别混沌!FMPy模型输出可视化全攻略:从基础图表到交互式仪表盘

告别混沌!FMPy模型输出可视化全攻略:从基础图表到交互式仪表盘

【免费下载链接】FMPy Simulate Functional Mockup Units (FMUs) in Python 【免费下载链接】FMPy 项目地址: https://gitcode.com/gh_mirrors/fm/FMPy

你是否曾为FMU (Functional Mockup Unit,功能模型单元)仿真结果的杂乱可视化而困扰?是否在调试复杂模型时因图表表达不足而浪费数小时?本文将系统讲解FMPy (Functional Mockup Interface for Python)中模型输出可视化的优化技巧,通过12个实战案例和7种进阶方案,帮你将原始仿真数据转化为直观易懂的工程洞察。读完本文,你将掌握从基础图表定制到交互式仪表盘开发的全流程技能,让你的仿真结果传达更精准的工程含义。

一、FMPy可视化核心原理与痛点分析

FMPy作为Python生态中主流的FMI标准实现库,提供了从FMU加载、仿真到结果可视化的完整工具链。其可视化功能主要通过fmpy.util模块中的plot_result()函数实现,该函数基于Plotly库构建交互式图表,支持多变量对比、事件标记和单位自动转换等核心功能。

1.1 数据结构基础:SimulationResult对象

FMPy仿真结果通常以结构化NumPy数组形式返回,包含时间序列数据和变量元信息:

# 典型仿真结果数据结构
result = simulate_fmu(
    filename='CoupledClutches.fmu',
    start_time=0,
    stop_time=1.5,
    output=['outputs[1]', 'outputs[2]', 'outputs[3]', 'outputs[4]']
)

print(result.dtype.names)  # 输出变量名称: ('time', 'outputs[1]', 'outputs[2]', ...)
print(result['time'].shape)  # 时间轴数组: (150,)
print(result['outputs[1]'].dtype)  # 变量数据类型: float64

这种结构将时间作为独立变量,所有仿真变量作为从属变量,形成典型的时间序列矩阵,为多变量对比可视化奠定基础。

1.2 默认可视化流程与局限

标准可视化调用通过plot_result()实现:

from fmpy.util import plot_result
plot_result(result=result, window_title="耦合离合器仿真结果")

这将生成包含所有输出变量的垂直排列子图,每个子图显示一个变量随时间的变化曲线。虽然便捷,但在工程实践中存在显著局限:

痛点具体表现影响
变量拥挤超过5个变量时图表高度超过屏幕无法直观比较变量关系
单位混乱不同物理量使用默认单位显示工程解读易产生误解
静态呈现缺乏数据点交互查询功能难以精确定位异常值
事件隐藏仅通过垂直线标记事件点,无详细信息事件与变量变化关联性不明确
导出限制图表格式和分辨率难以定制无法直接用于报告和论文

二、基础可视化优化:从默认到专业

2.1 变量筛选与布局控制

核心问题:默认显示所有输出变量导致信息过载
解决方案:通过names参数精确指定需可视化的变量,并优化子图布局

# 优化1: 筛选关键变量
plot_result(
    result=result,
    names=['outputs[1]', 'outputs[3]'],  # 仅显示两个关键变量
    height=600  # 固定图表高度
)

# 优化2: 自定义子图排列 (需直接调用create_plotly_figure)
from fmpy.util import create_plotly_figure
fig = create_plotly_figure(
    result=result,
    names=['outputs[1]', 'outputs[2]', 'outputs[3]', 'outputs[4]'],
    height=800
)
fig.update_layout(grid={'rows': 2, 'columns': 2})  # 2x2网格布局
fig.show()

效果对比

  • 默认布局:4个变量垂直排列,高度超过1200px
  • 优化布局:2x2网格排列,在800px高度内完整显示所有变量

2.2 单位系统与时间轴优化

FMPy的create_plotly_figure()函数内置了智能单位转换逻辑,可根据时间跨度自动选择合适的时间单位:

# 单位优化示例
fig = create_plotly_figure(
    result=result,
    time_unit='ms'  # 强制使用毫秒单位
)

# 自定义时间轴范围 (聚焦关键时间段)
fig.update_xaxes(range=[0.5, 1.0])  # 仅显示0.5-1.0秒区间
fig.show()

时间单位自动转换规则

时间跨度自动选择单位转换因子适用场景
<1ms'us' (微秒)×1e6高频动态系统
1ms-1s'ms' (毫秒)×1e3机电暂态过程
1s-10min's' (秒)×1常规动态仿真
10min-24h'min' (分钟)÷60长时间运行过程
>24h'days' (天)÷86400系统老化仿真

2.3 事件标记与异常突出

工程仿真中常需关注事件点(如状态切换、不连续点),FMPy通过events参数支持事件可视化:

# 事件可视化增强
plot_result(
    result=result,
    events=True,  # 标记事件点
    markers=True  # 显示数据点标记
)

# 自定义事件样式 (高级用法)
fig = create_plotly_figure(result=result, events=True)
# 修改事件线样式
for shape in fig.layout.shapes:
    if shape['type'] == 'line':  # 识别事件线
        shape['line']['color'] = '#ff4444'  # 红色事件线
        shape['line']['width'] = 2
        shape['line']['dash'] = 'dash'
fig.show()

事件点在时间轴上表现为重复的时间戳,create_plotly_figure()通过检测time数组中的重复值识别事件,并用黄色垂直线标记。通过自定义样式可增强事件的视觉辨识度。

三、进阶可视化技术:多维度分析与定制化

3.1 多变量相关性分析

对于多输入多输出系统,变量间的相关性分析至关重要。通过组合使用FMPy和Plotly的散点矩阵功能,可构建变量相关性分析面板:

import plotly.figure_factory as ff
import pandas as pd

# 转换为DataFrame便于分析
df = pd.DataFrame(result)

# 创建散点矩阵
fig = ff.create_scatterplotmatrix(
    df[['outputs[1]', 'outputs[2]', 'outputs[3]']],
    diag='kde',  # 对角线显示核密度估计
    height=800,
    title='变量相关性分析'
)
fig.update_layout(showlegend=True)
fig.show()

这种可视化方法特别适合识别变量间的线性/非线性关系,例如机械系统中转速与扭矩的耦合特性。

3.2 动态范围调整与对数刻度

对于包含大幅值变化的变量(如电力系统中的电压暂态),线性刻度可能掩盖关键细节。FMPy支持通过Plotly的轴类型设置实现对数刻度:

fig = create_plotly_figure(result=result, names=['outputs[1]'])

# 设置Y轴为对数刻度
fig.update_yaxes(
    type='log',  # 对数刻度
    exponentformat='E',  # 科学计数法显示
    title='电压 [V] (对数刻度)'
)

# 添加参考线
fig.add_hline(
    y=220, line_dash="dash", 
    annotation_text="额定电压",
    annotation_position="bottom right"
)
fig.show()

3.3 仿真结果与参考数据对比

工程验证中常需将仿真结果与实验数据或参考解对比,FMPy的plot_result()支持传入reference参数实现对比可视化:

# 加载参考数据
reference = np.genfromtxt('experimental_data.csv', delimiter=',', names=True)

# 对比可视化
plot_result(
    result=result,
    reference=reference,
    names=['outputs[1]']  # 指定对比变量
)

# 高级对比:自定义误差带
fig = create_plotly_figure(result=result, names=['outputs[1]'])

# 添加参考数据
fig.add_trace(go.Scatter(
    x=reference['time'],
    y=reference['measured_value'],
    name='实验数据',
    mode='markers',
    marker=dict(color='red', size=6)
))

# 添加误差带
fig.add_trace(go.Scatter(
    x=reference['time'],
    y=reference['measured_value'] + reference['uncertainty'],
    name='上误差界',
    mode='lines',
    line=dict(width=0),
    showlegend=False
))
fig.add_trace(go.Scatter(
    x=reference['time'],
    y=reference['measured_value'] - reference['uncertainty'],
    fill='tonexty',  # 填充到上误差界
    fillcolor='rgba(255,0,0,0.2)',
    line=dict(width=0),
    name='测量不确定度',
))
fig.show()

四、批量可视化与报告自动化

4.1 多参数仿真结果对比

参数扫描分析(如不同设计参数下的系统响应)需要对比多个仿真结果。通过自定义函数可实现批量处理与可视化:

def compare_parameter_variations(parameters, results, variable='outputs[1]'):
    """对比不同参数下的仿真结果"""
    fig = go.Figure()
    
    for param_value, result in zip(parameters, results):
        fig.add_trace(go.Scatter(
            x=result['time'],
            y=result[variable],
            name=f'频率={param_value}Hz'
        ))
    
    fig.update_layout(
        title=f'{variable}随频率变化曲线',
        xaxis_title='时间 [s]',
        yaxis_title='输出扭矩 [N·m]',
        legend_title='参数设置'
    )
    return fig

# 批量仿真不同参数
parameters = [0.2, 0.4, 0.6, 0.8]
results = []
for freq in parameters:
    result = simulate_fmu(
        filename='CoupledClutches.fmu',
        start_values={'CoupledClutches1_freqHz': freq},
        output=['outputs[1]']
    )
    results.append(result)

# 生成对比图表
fig = compare_parameter_variations(parameters, results)
fig.show()

4.2 自动化报告生成

结合Jinja2模板引擎和FMPy可视化功能,可实现仿真报告的自动化生成:

from jinja2 import Template
import plotly.io as pio

# 1. 生成关键图表
fig1 = create_plotly_figure(result=result, names=['outputs[1]', 'outputs[2]'])
fig2 = create_plotly_figure(result=result, names=['outputs[3]', 'outputs[4]'])

# 2. 导出为HTML
chart1_html = pio.to_html(fig1, full_html=False)
chart2_html = pio.to_html(fig2, full_html=False)

# 3. 使用模板生成报告
template = Template("""
<h1>耦合离合器系统仿真报告</h1>
<p>仿真时间: {{ start_time }}至{{ stop_time }}秒</p>

<h2>主要输出特性</h2>
{{ chart1 }}

<h2>辅助变量响应</h2>
{{ chart2 }}

<h2>关键指标</h2>
<table>
    <tr><th>指标</th><th>数值</th><th>单位</th></tr>
    <tr><td>最大输出扭矩</td><td>{{ max_torque }}</td><td>N·m</td></tr>
    <tr><td>稳态误差</td><td>{{ steady_state_error }}%</td><td></td></tr>
</table>
""")

# 4. 渲染模板
report_html = template.render(
    start_time=0,
    stop_time=1.5,
    chart1=chart1_html,
    chart2=chart2_html,
    max_torque=np.max(result['outputs[1]']),
    steady_state_error=0.8
)

# 5. 保存报告
with open('simulation_report.html', 'w') as f:
    f.write(report_html)

五、性能优化与大型数据集可视化

5.1 数据降采样策略

对于高频仿真数据(如电力电子系统的微秒级仿真),原始数据点可能达数百万个,直接可视化会导致性能下降。FMPy提供间接支持通过数据降采样提升交互性能:

def downsample_result(result, max_points=1000):
    """智能降采样,保留关键特征点"""
    n_samples = len(result)
    if n_samples <= max_points:
        return result
        
    # 计算采样间隔
    interval = max(1, n_samples // max_points)
    
    # 保留事件点
    time = result['time']
    events = np.where(np.diff(time) == 0)[0] + 1  # 事件点索引
    
    # 生成采样索引
    indices = np.unique(np.concatenate([
        np.arange(0, n_samples, interval),  # 均匀采样
        events  # 事件点
    ]))
    
    return result[np.sort(indices)]

# 降采样应用
downsampled = downsample_result(result, max_points=1000)
plot_result(result=downsampled)

5.2 3D可视化与参数空间探索

对于包含空间分布的模型(如温度场、应力分布),FMPy可结合Plotly的3D功能实现空间可视化:

# 假设result包含空间坐标数据
fig = go.Figure(data=[go.Scatter3d(
    x=result['x_coord'],
    y=result['y_coord'],
    z=result['temperature'],
    mode='markers',
    marker=dict(
        size=5,
        color=result['temperature'],  # 颜色映射温度值
        colorscale='Viridis',  # 温度色标
        colorbar_title='温度 [°C]'
    )
)])

fig.update_layout(
    scene=dict(
        xaxis_title='X坐标 [mm]',
        yaxis_title='Y坐标 [mm]',
        zaxis_title='温度 [°C]'
    ),
    title='电机定子温度分布'
)
fig.show()

六、实战案例:耦合离合器系统动态特性分析

以下通过完整案例展示FMPy可视化优化的全流程,以CoupledClutches.fmu模型为例,分析不同输入频率下的系统动态响应。

6.1 基础仿真与默认可视化

from fmpy import simulate_fmu
from fmpy.util import plot_result

# 基础仿真
result = simulate_fmu(
    filename='CoupledClutches.fmu',
    start_time=0,
    stop_time=1.5,
    output=['outputs[1]', 'outputs[2]', 'outputs[3]', 'outputs[4]']
)

# 默认可视化
plot_result(result=result, window_title="耦合离合器默认仿真结果")

6.2 多参数扫描与对比可视化

# 定义参数扫描范围
frequencies = [0.2, 0.4, 0.6, 0.8]  # 输入频率
results = []

# 批量仿真
for freq in frequencies:
    res = simulate_fmu(
        filename='CoupledClutches.fmu',
        start_time=0,
        stop_time=1.5,
        start_values={'CoupledClutches1_freqHz': freq},
        output=['outputs[1]']
    )
    results.append(res)

# 创建对比图表
import plotly.graph_objects as go

fig = go.Figure()
for freq, res in zip(frequencies, results):
    fig.add_trace(go.Scatter(
        x=res['time'],
        y=res['outputs[1]'],
        name=f'频率={freq}Hz'
    ))

fig.update_layout(
    title='不同输入频率下的离合器输出扭矩',
    xaxis_title='时间 [s]',
    yaxis_title='输出扭矩 [N·m]',
    legend_title='输入频率',
    template='plotly_white'
)

# 添加关键点标注
fig.add_annotation(
    x=0.8, y=12,
    text="共振点",
    showarrow=True,
    arrowhead=1
)

fig.show()

6.3 事件分析与动态特性提取

# 识别事件点
time = result['time']
events = np.where(np.diff(time) == 0)[0] + 1  # 事件点索引

# 提取事件时刻的变量值
event_times = time[events]
event_values = result['outputs[1]'][events]

# 创建事件分析图表
fig = go.Figure()

# 主曲线
fig.add_trace(go.Scatter(
    x=time, y=result['outputs[1]'],
    name='输出扭矩', line=dict(width=2)
))

# 事件点标记
fig.add_trace(go.Scatter(
    x=event_times, y=event_values,
    name='事件点', mode='markers',
    marker=dict(color='red', size=8, symbol='star')
))

# 事件统计
event_stats = pd.DataFrame({
    '时间': event_times,
    '扭矩值': event_values,
    '变化率': np.diff(event_values, prepend=0)
})

# 在图表中嵌入统计表格
fig.add_annotation(
    x=0.05, y=0.95, xref='paper', yref='paper',
    text=event_stats.to_html(index=False),
    showarrow=False,
    bgcolor='white',
    bordercolor='black',
    borderwidth=1
)

fig.show()

七、总结与最佳实践

FMPy提供了强大而灵活的模型输出可视化工具,通过合理应用本文介绍的优化技巧,可显著提升仿真结果的表达力和工程洞察力。以下是关键最佳实践总结:

7.1 可视化工作流建议

  1. 数据准备阶段:明确可视化目标,筛选关键变量,避免信息过载
  2. 基础可视化:使用plot_result()快速生成初始图表,识别主要特征
  3. 定制优化:根据数据特性选择合适的可视化类型(线性/对数刻度、2D/3D等)
  4. 对比分析:添加参考数据、事件标记和统计信息增强工程含义
  5. 报告输出:选择合适的导出格式(PNG/SVG/PDF),确保分辨率满足需求

7.2 性能与兼容性考虑

  • 对于大型数据集(>10万点),始终应用降采样
  • 为确保跨平台兼容性,优先使用SVG格式导出矢量图
  • Web应用中考虑使用轻量化图表(通过include_plotlyjs='cdn'减少加载时间)

7.3 进阶学习资源

  • FMPy官方文档:https://fmpy.readthedocs.io
  • Plotly图表库:https://plotly.com/python/
  • FMI标准规范:https://fmi-standard.org/

通过掌握这些可视化技巧,你将能够更有效地从仿真数据中提取工程洞察,加速模型验证和设计优化过程。无论是学术研究、工程开发还是教学演示,高质量的可视化都将成为你传达复杂动态系统行为的强大工具。

【免费下载链接】FMPy Simulate Functional Mockup Units (FMUs) in Python 【免费下载链接】FMPy 项目地址: https://gitcode.com/gh_mirrors/fm/FMPy

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值