如何在matplotlib 3D散点图点云中心上方绘制自定义对象
Matplotlib 3D点云上方叠加自定义对象问题
我编写了如下代码:
import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation from matplotlib import animation %matplotlib inline plt.ion() fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.view_init(azim=270, elev=90) ax.set_xlabel('X axis') ax.set_ylabel('Y axis') ax.set_zlabel('Z axis') X = -df['x'] Y = -df['y'] Z = -df['z'] ax.scatter(X,Y,Z, color = 'red') plt.draw()
运行上述代码得到的绘图效果如下:
我希望能够在生成的点云中心上方叠加绘制对象,预期效果如下图所示:
请问该需求是否可以实现?是否有合适的实现方案?
可行实现方案
该需求完全可以实现,根据叠加对象是否需要跟随3D视角同步变换,有两类成熟方案:
方案1:同3D坐标系绘制(对象与点云相对位置固定,随视角同步旋转/缩放)
这是和预期效果最匹配的方案,实现步骤:
计算点云中心坐标与叠加位置
import numpy as np # 计算点云三轴中心 cx, cy, cz = np.mean(X), np.mean(Y), np.mean(Z) # 计算叠加高度:取点云Z轴最大值以上,预留10%点云高度的间距,可按需调整 z_offset = (Z.max() - Z.min()) * 0.1 obj_z_pos = Z.max() + z_offset调用对应3D绘图接口绘制目标对象即可:
- 绘制立方体/长方体:使用
ax.bar3d() - 绘制球体、自定义曲面:使用
ax.plot_surface()或ax.plot_trisurf() - 绘制箭头、线段:使用
ax.quiver()或ax.plot()
示例:在中心上方叠加一个边长为点云尺度1/10的蓝色半透明立方体
cube_len = (X.max() - X.min()) * 0.1 ax.bar3d(cx - cube_len/2, cy - cube_len/2, obj_z_pos, dx=cube_len, dy=cube_len, dz=cube_len, color='blue', alpha=0.7)- 绘制立方体/长方体:使用
该方案下叠加对象和点云处于同一3D空间,任意调整视角都不会出现相对位置错位。
方案2:2D锚定绘制(对象固定在视图对应位置,不随3D视角变化)
如果需要叠加文字、2D标识这类不需要跟随3D视角旋转的元素,可以直接使用2D坐标锚定,无需计算3D位置:
# 采用子图相对坐标,(0.5, 0.9)对应水平居中、垂直方向距顶部10%的位置 ax.text(0.5, 0.9, "目标标记", transform=ax.transAxes, ha='center', va='center', fontsize=14, color='blue')
如果需要叠加图片,可搭配matplotlib.offsetbox.OffsetImage和AnnotationBbox实现,同样锚定在2D坐标点即可。
补充提示:当前代码中使用了
%matplotlib inline魔法命令,该模式下plt.ion()交互模式不会生效,如果需要拖拽调整3D视角,Jupyter环境下请替换为%matplotlib notebook,本地脚本环境直接移除该行魔法命令即可。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

