Matplotlib可视化:面试官问“你怎么验证SLAM算法”,画图是最直接的答案
NumPy的两篇聊完了。今天说Matplotlib——Python的画图库。
做机器人算法开发,画图和写算法一样重要。你写了一个路径规划算法,不画出来怎么知道对不对?你跑了一个SLAM系统,不可视化轨迹怎么知道漂移了多少?
先说个事。
我之前面试一个做SLAM的候选人,聊到他的算法效果。他说"精度还不错"。面试官问:"你怎么评估的?有没有可视化的对比?"
他说:"我算了一个RMSE数值。"
面试官又问:"能把轨迹画出来看看吗?"
他愣了一下,说:"代码里没有画图的部分。"
这就有点减分了。做算法不画图,就像做实验不记录数据——你自己可能心里有数,但别人没法验证。
Matplotlib基础:五分钟画出第一张图
import matplotlib.pyplot as plt
import numpy as np
# 最简单的折线图
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.plot(x, y)
plt.xlabel("Time (s)")
plt.ylabel("Value")
plt.title("Sensor Signal")
plt.grid(True)
plt.savefig("signal.png", dpi=150)
plt.show()
这几行代码就能生成一张带标题、坐标轴标签、网格线的正弦波图。savefig保存图片到文件,show在窗口中显示。
在Jupyter Notebook里,加一行%matplotlib inline就能让图直接嵌在代码下方,做数据分析的时候特别方便。
机器人开发中的常用图表
散点图——画点云和地图:
# 模拟2D激光雷达扫描
angles = np.linspace(-np.pi/2, np.pi/2, 360)
ranges = 5.0 + np.random.randn(360) * 0.1
x = ranges * np.cos(angles)
y = ranges * np.sin(angles)
plt.scatter(x, y, s=1, c='blue')
plt.axis('equal')
plt.title("Lidar Scan")
plt.show()
多子图——对比不同算法:
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
# 原始路径
axes[0].plot(path_x, path_y, 'b-')
axes[0].set_title("Original Path")
# 平滑后
axes[1].plot(smooth_x, smooth_y, 'g-')
axes[1].set_title("Smoothed Path")
# 对比
axes[2].plot(path_x, path_y, 'b-', label="Original")
axes[2].plot(smooth_x, smooth_y, 'r--', label="Smoothed")
axes[2].legend()
plt.tight_layout()
plt.savefig("path_comparison.png")
热力图——画代价地图:
# 模拟代价地图
costmap = np.random.rand(50, 50)
costmap[20:30, 20:30] = 1.0 # 障碍物
plt.imshow(costmap, cmap='hot', interpolation='nearest')
plt.colorbar(label="Cost")
plt.title("Cost Map")
plt.show()
SLAM轨迹可视化
做SLAM最常用的一种图:估计轨迹vs真实轨迹的对比。
def plot_trajectory(estimated, ground_truth):
"""
estimated, ground_truth: shape (N, 3), 每行是 [x, y, theta]
"""
fig, ax = plt.subplots(1, 1, figsize=(8, 8))
ax.plot(ground_truth[:, 0], ground_truth[:, 1],
'b-', linewidth=2, label="Ground Truth")
ax.plot(estimated[:, 0], estimated[:, 1],
'r--', linewidth=2, label="Estimated")
# 标记起点和终点
ax.plot(ground_truth[0, 0], ground_truth[0, 1], 'go', markersize=10, label="Start")
ax.plot(ground_truth[-1, 0], ground_truth[-1, 1], 'rs', markersize=10, label="End")
ax.set_xlabel("X (m)")
ax.set_ylabel("Y (m)")
ax.set_title("SLAM Trajectory Comparison")
ax.legend()
ax.grid(True)
ax.axis('equal')
plt.tight_layout()
plt.savefig("trajectory.png", dpi=150)
plt.show()
这种图一画出来,算法效果一目了然。漂移了多少、哪里有回环校正、整体趋势对不对,全都能看到。
动态更新:实时显示传感器数据
Matplotlib还支持动态更新图表,适合实时显示传感器数据:
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
scatter = ax.scatter([], [], s=1)
ax.set_xlim(-10, 10)
ax.set_ylim(-10, 10)
def update(frame):
# 每帧更新扫描数据
angles = np.linspace(-np.pi/2, np.pi/2, 360)
ranges = get_latest_scan() # 获取最新扫描数据
x = ranges * np.cos(angles)
y = ranges * np.sin(angles)
scatter.set_offsets(np.column_stack([x, y]))
return scatter
ani = FuncAnimation(fig, update, interval=100)
plt.show()
这个在做调试工具的时候很有用——你可以实时看到激光雷达的扫描画面、机器人的位置更新等。
如果是三维数据的可视化,Matplotlib的mpl_toolkits.mplot3d模块也能应付。比如画三维点云或者三维轨迹,用ax.scatter3D和ax.plot3D就行。不过对于大规模的三维点云(几十万个点以上),Matplotlib会比较吃力,这时候建议用Open3D或者Mayavi这类专业的三维可视化库。
调试图表的小技巧
实际项目中画图经常需要反复调整参数,这里分享几个提效技巧。第一,用plt.subplots()一次性创建多个子图,比多次调用plt.figure()快很多。第二,在循环里画图一定要加plt.close()释放内存,不然跑几百次迭代后内存就爆了。第三,保存高清用plt.savefig并设置dpi=300和bbox_inches=tight,这样出来的图放报告里不会糊。面试时如果说调试SLAM算法全靠Matplotlib,面试官会觉得你确实干过实事。
给正在准备面试的你
Matplotlib在面试中很少直接考,但在实际工作中是必备技能。如果你面试的时候能展示几张自己画的算法效果图——SLAM轨迹对比、路径规划可视化、传感器数据分析图——比说一百句"我算法精度很高"都有说服力。
建议把你做过的算法项目都画几张图,保存到portfolio里。面试的时候拿出来,效果非常好。
下篇聊深度相机原理对比——结构光、ToF、双目各自优劣。这是传感器方向的基础知识,面试中经常被问到。
如果这篇文章对你有帮助,欢迎点赞、在看、转发三连。 你的支持是我持续更新的最大动力。
「机器人软件开发面试·从入门到精通」连载系列 上一篇:第72篇 NumPy进阶——矩阵运算与机器人运动学计算 下一篇预告:第74篇 ROS2中的Python——和C++节点的混合编程
有任何问题欢迎评论区留言,我会尽量回复。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)