如何在Matplotlib/Plotly 3D绘图中添加外部3D模型(如矩形框架)
如何在Matplotlib/Plotly 3D绘图中添加外部3D模型(如矩形框架)
嗨,我来帮你搞定在3D图里添加这类矩形框架(门)的问题!不管是用Matplotlib还是Plotly,都有实用的方法,我分两种库给你详细拆解:
一、Matplotlib实现方案
Matplotlib本身对复杂外部3D模型的原生支持不算强,但针对你需要的矩形门这类规则框架,我们可以自定义构建整体对象,或者借助第三方库加载外部模型:
1. 自定义构建矩形门框架(作为整体对象)
如果只是类似图里的矩形框架门,完全可以自己定义顶点和边,用Line3DCollection把所有边打包成一个对象,这样后续平移、旋转都很方便,不会散成一堆点:
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d.art3d import Line3DCollection from mpl_toolkits.mplot3d import Axes3D import numpy as np # 定义矩形门的顶点(默认在原点位置) # 格式:[x, y, z],分别是门的四个角点(底部两个,顶部两个) door_vertices = np.array([ [0, 0, 0], # 底部左 [1, 0, 0], # 底部右 [1, 0, 2], # 顶部右 [0, 0, 2], # 顶部左 ]) # 定义门框架的边:每个边是两个顶点的索引 door_edges = [ [0, 1], [1, 2], [2, 3], [3, 0], # 门的四条边框 [0, 3], [1, 2] # 可选:添加对角线,按需调整 ] # 把边转换成Line3DCollection需要的格式 edge_segments = [[door_vertices[i], door_vertices[j]] for i, j in door_edges] # 创建3D绘图 fig = plt.figure() ax = fig.add_subplot(projection='3d') # 添加门框架作为一个整体对象 door_collection = Line3DCollection(edge_segments, color='darkblue', linewidths=2) ax.add_collection3d(door_collection) # 可以轻松平移整个门:比如把门移到x=2, y=1的位置 door_collection.set_offsets([2, 1]) # 设置坐标轴范围 ax.set_xlim(0, 5) ax.set_ylim(0, 5) ax.set_zlim(0, 3) ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') plt.show()
2. 加载外部3D模型(如OBJ格式)
如果你的框架是复杂的外部模型,可以用trimesh库加载,然后转成Matplotlib可渲染的格式:
- 先安装依赖:
pip install trimesh - 代码示例:
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import trimesh # 加载OBJ格式的3D模型(替换成你的门模型路径) mesh = trimesh.load('your_door_model.obj') # 提取模型的顶点和面 vertices = mesh.vertices faces = mesh.faces # 创建3D绘图 fig = plt.figure() ax = fig.add_subplot(projection='3d') # 绘制模型,作为整体对象 ax.plot_trisurf(vertices[:, 0], vertices[:, 1], vertices[:, 2], triangles=faces, color='lightblue', edgecolor='darkblue') # 平移模型:比如整体偏移x=3, y=2 ax.plot_trisurf(vertices[:, 0]+3, vertices[:, 1]+2, vertices[:, 2], triangles=faces, color='lightblue', edgecolor='darkblue') # 设置坐标轴 ax.set_xlim(0, 6) ax.set_ylim(0, 6) ax.set_zlim(0, 4) plt.show()
二、Plotly实现方案
Plotly的3D交互性更好,不管是自定义框架还是加载外部模型都更顺手:
1. 自定义矩形门框架(整体对象)
用go.Scatter3d的mode='lines'可以把所有边组合成一个Trace(相当于一个整体对象),方便统一调整样式和位置:
import plotly.graph_objects as go import numpy as np # 定义门的顶点 door_vertices = np.array([ [0, 0, 0], [1, 0, 0], [1, 0, 2], [0, 0, 2] ]) # 定义门的边的连接顺序,确保所有框架边都被覆盖 edge_order = [0,1,2,3,0, # 外围边框闭合 0,3, 1,2] # 补充竖边(可选,按需调整) # 提取边的x/y/z坐标 x = door_vertices[edge_order, 0] y = door_vertices[edge_order, 1] z = door_vertices[edge_order, 2] # 创建Figure fig = go.Figure() # 添加门框架作为一个Trace(整体) fig.add_trace(go.Scatter3d( x=x, y=y, z=z, mode='lines', line=dict(color='darkblue', width=4), name='Door Frame' )) # 平移门:直接修改x/y/z数组即可,比如整体移到x=2, y=1的位置 fig.add_trace(go.Scatter3d( x=x+2, y=y+1, z=z, mode='lines', line=dict(color='darkgreen', width=4), name='Door Frame (Moved)' )) # 设置布局 fig.update_layout( scene=dict( xaxis=dict(range=[0,5]), yaxis=dict(range=[0,5]), zaxis=dict(range=[0,3]), xaxis_title='X', yaxis_title='Y', zaxis_title='Z' ) ) fig.show()
2. 加载外部3D模型
Plotly可以直接用go.Mesh3d来渲染外部模型的网格,结合trimesh加载:
- 先安装依赖:
pip install trimesh - 代码示例:
import plotly.graph_objects as go import trimesh # 加载外部OBJ模型(替换成你的门模型路径) mesh = trimesh.load('your_door_model.obj') # 提取顶点和面索引(Plotly的Mesh3d需要面是列表格式) vertices = mesh.vertices faces = mesh.faces.tolist() # 创建Figure fig = go.Figure() # 添加模型作为一个Trace(整体) fig.add_trace(go.Mesh3d( x=vertices[:,0], y=vertices[:,1], z=vertices[:,2], i=[face[0] for face in faces], j=[face[1] for face in faces], k=[face[2] for face in faces], color='lightblue', opacity=0.8, name='External Door Model' )) # 平移模型:直接给顶点加偏移量 fig.add_trace(go.Mesh3d( x=vertices[:,0]+3, y=vertices[:,1]+2, z=vertices[:,2], i=[face[0] for face in faces], j=[face[1] for face in faces], k=[face[2] for face in faces], color='lightgreen', opacity=0.8, name='Moved Door Model' )) fig.update_layout( scene=dict( xaxis_range=[0,6], yaxis_range=[0,6], zaxis_range=[0,4] ) ) fig.show()
小提示
- 对于规则的矩形框架,我更推荐自定义构建,因为不需要依赖外部模型文件,而且调整尺寸、位置、样式都更灵活;
- 不管用哪种库,把元素做成单个Trace/Collection对象,后续调整(平移、旋转、缩放)会比零散的点或线方便太多,完全符合你“作为一个对象”的需求!
备注:内容来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

