基于Matplotlib在UAV着陆平面上绘制立方体的技术求助
无人机着陆可视化:立方体绘制错误修复与动态适配方案
1. 解决 AttributeError: 'int' object has no attribute 'ndim' 报错
该报错核心原因是将整数/标量传入了需要numpy数组的Matplotlib 3D绘图接口,比如你的createVertices函数返回的顶点格式不符合要求,或是绘图时直接传入了单个数值而非坐标数组。
修正后的立方体顶点生成函数
确保返回的是numpy数组格式的顶点坐标:
import numpy as np def createVertices(cube_center, cube_size): half_size = cube_size / 2.0 # 生成8个顶点的三维坐标,返回numpy数组 return np.array([ [cube_center[0]-half_size, cube_center[1]-half_size, cube_center[2]-half_size], [cube_center[0]+half_size, cube_center[1]-half_size, cube_center[2]-half_size], [cube_center[0]+half_size, cube_center[1]+half_size, cube_center[2]-half_size], [cube_center[0]-half_size, cube_center[1]+half_size, cube_center[2]-half_size], [cube_center[0]-half_size, cube_center[1]-half_size, cube_center[2]+half_size], [cube_center[0]+half_size, cube_center[1]-half_size, cube_center[2]+half_size], [cube_center[0]+half_size, cube_center[1]+half_size, cube_center[2]+half_size], [cube_center[0]-half_size, cube_center[1]+half_size, cube_center[2]+half_size], ])
正确绘制立方体的代码
结合已有的着陆平面,通过绘制立方体的12条边完成可视化:
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # 绘制着陆平面(z=0的XY平面) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') xx, yy = np.meshgrid(np.linspace(-10, 10, 100), np.linspace(-10, 10, 100)) zz = np.zeros_like(xx) ax.plot_surface(xx, yy, zz, alpha=0.3, color='gray') # 生成立方体(中心在(0,0,2),边长2) cube_vertices = createVertices([0,0,2], 2) # 定义立方体的12条边连接关系 edges = [(0,1),(1,2),(2,3),(3,0),(4,5),(5,6),(6,7),(7,4),(0,4),(1,5),(2,6),(3,7)] # 遍历绘制每条边 for start_idx, end_idx in edges: start = cube_vertices[start_idx] end = cube_vertices[end_idx] ax.plot3D([start[0], end[0]], [start[1], end[1]], [start[2], end[2]], color='red') ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') plt.show()
2. 适配百余个测试用例的动态绘制方案
使用Matplotlib的FuncAnimation实现高效的动态更新,避免重复创建绘图对象,提升性能:
from matplotlib.animation import FuncAnimation # 模拟100个测试用例:每个用例对应立方体的中心坐标 test_cases = [np.array([i*0.2, i*0.1, 2 + i*0.05]) for i in range(100)] # 初始化绘图框架 fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.plot_surface(xx, yy, zz, alpha=0.3, color='gray') ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') # 预创建立方体线条对象(避免每帧重复创建) cube_lines = [] for _ in edges: line, = ax.plot3D([], [], [], color='red') cube_lines.append(line) # 帧更新函数:仅修改线条数据,不重建对象 def update(frame): current_center = test_cases[frame] current_vertices = createVertices(current_center, 2) for idx, (start_idx, end_idx) in enumerate(edges): start = current_vertices[start_idx] end = current_vertices[end_idx] cube_lines[idx].set_data([start[0], end[0]], [start[1], end[1]]) cube_lines[idx].set_3d_properties([start[2], end[2]]) return cube_lines # 创建并播放动画 ani = FuncAnimation(fig, update, frames=len(test_cases), interval=50, blit=True) plt.show() # 可选:保存动画到文件 # ani.save('uav_landing_demo.mp4', writer='ffmpeg')
关键优化点
- 预创建所有绘图对象,每帧仅更新数据,大幅提升百级用例的运行效率
- 通过
interval参数控制动画播放速度(单位:毫秒) - 确保测试用例的坐标格式为numpy数组或浮点列表,避免再次触发类型错误
内容的提问来源于stack exchange,提问作者Wanja Wilson
相关产品推荐
相关产品推荐

