<think>好的,我需要帮用户写一个Python函数,用来对比转换前后的六个自由度数据,分别在6个子图中显示时序。用户提供了两个DataFrame,df_data和df_res,它们的列名不同,需要正确映射。
首先,我得明确转换前后的对应关系。转换前的df_data包含roll, pitch, yaw,以及surge_vel, sway_vel, heave_vel作为线速度。转换后的df_res有roll, pitch, yaw,以及x_velocity, y_velocity, z_velocity。可能需要确认surge_vel对应x_velocity,sway_vel对应y_velocity,heave_vel对应z_velocity。这点用户已经提到转换前后的六个自由度是pitch, roll, yaw和x_velo, y_velo, z_velo,所以应该对应正确。
接下来,函数的结构需要用到matplotlib的子图功能,创建6个子图,每个子图显示一个自由度的转换前后数据。要确保时间戳对齐,可能需要检查时间戳列是否存在,并且数据是按时间排序的。
然后,考虑绘图的细节。每个子图应该有标题,坐标轴标签,图例,网格线等。可能需要使用plt.subplots来创建6个子图,布局为3行2列或者2行3列,根据用户需求调整。这里用户要求6个子图,所以应该是3行2列。
数据方面,转换前的线速度列是surge_vel, sway_vel, heave_vel,对应转换后的x_velocity, y_velocity, z_velocity。需要将这些列名对应起来,可能用一个字典来映射。
另外,时间戳的处理,可能需要将时间戳转换为相对时间,比如从第一个时间点开始的秒数,这样x轴显示更清晰。还需要确保两个DataFrame的时间戳范围一致,或者处理可能的时间偏移。
在绘图时,每个子图绘制两条曲线,转换前和转换后的数据,用不同颜色区分,比如蓝色和橙色。需要处理可能的单位或量纲差异,如果有的话,但用户可能已经确保转换后的数据是正确的,所以直接对比即可。
最后,调整图表布局,防止子图重叠,使用tight_layout,并显示图形。可能需要设置合适的图形大小,比如12x8英寸,保证可读性。
现在,把这些步骤转化为代码。首先导入必要的库,matplotlib.pyplot和pandas。然后定义函数,接受df_data和df_res作为参数。创建6个子图,遍历每个自由度,分别绘制转换前后的数据。
需要注意的是,转换前后的列名不同,所以需要建立映射关系。例如,pitch在转换前是'pitch',转换后也是'pitch';而x_velocity对应surge_vel等。需要明确每个子图对应的列:
- pitch: df_data['pitch'] vs df_res['pitch']
- roll: df_data['roll'] vs df_res['roll']
- yaw: df_data['yaw'] vs df_res['yaw']
- x_velo: df_data['surge_vel'] vs df_res['x_velocity']
- y_velo: df_data['sway_vel'] vs df_res['y_velocity']
- z_velo: df_data['heave_vel'] vs df_res['z_velocity']
然后,每个子图绘制两条曲线,设置标签、标题、图例等。可能需要处理时间戳为相对时间,例如将timestamp列转换为从0开始的时间序列。
检查数据是否存在缺失或时间戳不匹配的情况,如果有必要的话,可能需要先对齐数据,但用户可能已经处理好了这部分。函数中暂时不处理,假设时间戳对齐。
现在编写代码,测试可能的错误,比如列名不存在,或者数据为空。但用户提供的列名已经明确,所以假设输入正确。
最后,返回图形,用户可以在Jupyter notebook中显示,或者保存为图片。</think>以下是一个实现该功能的Python函数,使用matplotlib进行6自由度时序对比:
```python
import matplotlib.pyplot as plt
import pandas as pd
def plot_6dof_comparison(df_data, df_res):
"""
绘制六自由度转换前后对比时序图
参数:
df_data : 原始数据DataFrame
df_res : 转换后数据DataFrame
"""
# 创建6个子图(3行×2列)
fig, axes = plt.subplots(3, 2, figsize=(12, 8))
plt.subplots_adjust(hspace=0.5, wspace=0.3)
# 设置对比参数映射关系(原始数据列 : 转换后数据列)
comparisons = {
'pitch': ('pitch', 'pitch'),
'roll': ('roll', 'roll'),
'yaw': ('yaw', 'yaw'),
'x_velo': ('surge_vel', 'x_velocity'),
'y_velo': ('sway_vel', 'y_velocity'),
'z_velo': ('heave_vel', 'z_velocity')
}
# 转换时间戳为相对时间(秒)
for df in [df_data, df_res]:
if 'timestamp' in df.columns:
df['rel_time'] = (df['timestamp'] - df['timestamp'].iloc[0]) / 1e9 # 假设时间戳是纳秒级
# 遍历每个自由度绘制对比
for idx, (title, (col_orig, col_trans)) in enumerate(comparisons.items()):
ax = axes[idx//2, idx%2]
# 绘制原始数据
ax.plot(df_data['rel_time'], df_data[col_orig],
label='原始数据', alpha=0.7, linewidth=1.5)
# 绘制转换数据
ax.plot(df_res['rel_time'], df_res[col_trans],
label='转换数据', alpha=0.7, linewidth=1.5, linestyle='--')
# 设置子图格式
ax.set_title(f'{title.upper()} 对比')
ax.set_xlabel('时间 (s)')
ax.set_ylabel(title.split('_')[0] + ('角 (rad)' if '_velo' not in title else '速度 (m/s)'))
ax.grid(True, linestyle='--', alpha=0.5)
ax.legend()
plt.suptitle("六自由度数据转换前后对比", y=0.98, fontsize=14)
plt.tight_layout()
plt.show()
```
使用说明:
1. 函数接受两个DataFrame参数:
- `df_data`:原始数据,包含surge_vel/sway_vel/heave_vel等列
- `df_res`:转换后数据,包含x_velocity/y_velocity/z_velocity等列
2. 自动处理时间戳:
- 将时间戳转换为相对时间(从第一个数据点开始的秒数)
- 假设时间戳为纳秒级(如Unix时间戳),如果不是需要调整除数
3. 可视化特征:
- 使用虚线区分原始数据和转换数据
- 自动设置坐标轴标签和单位
- 每个子图包含图例和网格线
- 自适应布局防止重叠
调用示例:
```python
plot_6dof_comparison(df_data, df_res)
```
输出效果:
- 生成3行×2列共6个子图
- 前三图为姿态角(pitch, roll, yaw)对比
- 后三图为线速度(x, y, z)对比
- 每个子图包含原始数据与转换数据的时序曲线
注意事项:
1. 确保两个DataFrame的时间戳范围一致
2. 如果时间戳单位不是纳秒,需要修改`rel_time`计算中的除数
3. 建议在Jupyter Notebook中使用`%matplotlib inline`命令显示图像