如何在Plotly中为3D曲线与投影面间的连接曲面着色?
解决Plotly 3D曲线与投影间垂直曲面着色问题
问题说明
需要为plotly.graph_objects创建的3D曲线与其在x-y平面(z=350)的投影之间的垂直区域添加着色曲面,尝试用Mesh3d实现但未成功,当前仅显示曲线和垂直线。
解决方案
要实现垂直曲面着色,需正确构建Mesh3d的顶点坐标和三角面索引。垂直曲面由上下两条曲线(原3D曲线和z=350的投影)的顶点依次连接而成,通过生成相邻顶点组成的三角面来构建完整曲面。
修改后完整代码
import pandas as pd import plotly.graph_objects as go import numpy as np # 读取数据(替换为你的文件路径) data = pd.read_excel(r"你的数据文件路径.xlsx") x = data['x'].values y = data['y'].values z = data['alt'].values z_min_adjusted = np.maximum(z, 350) def plot_3d_course_profile(x, y, z, color_attribute, colorbar_label): fig = go.Figure() # ---------------------- 新增垂直着色曲面 ---------------------- # 构建Mesh3d的顶点:先存上方曲线点,再存下方投影点 n_points = len(x) x_mesh = np.concatenate([x, x]) y_mesh = np.concatenate([y, y]) z_mesh = np.concatenate([z, np.full(n_points, 350)]) # 构建三角面索引:每相邻的四个顶点组成两个三角形 faces = [] for i in range(n_points - 1): # 第一个三角形:上方当前点、上方下一点、下方当前点 faces.append([i, i+1, i + n_points]) # 第二个三角形:上方下一点、下方下一点、下方当前点 faces.append([i+1, i+1 + n_points, i + n_points]) # 添加Mesh3d曲面 fig.add_trace(go.Mesh3d( x=x_mesh, y=y_mesh, z=z_mesh, i=[face[0] for face in faces], j=[face[1] for face in faces], k=[face[2] for face in faces], color=color_attribute, colorscale='Jet', opacity=0.6, colorbar=dict( title=dict( text=colorbar_label, font=dict(size=14, color='black') ), thickness=20, len=0.6, tickfont=dict(size=12, color='black'), tickmode='linear', tickformat='.2f', outlinewidth=1, outlinecolor='black' ) )) # ---------------------- 原有曲线和投影线 ---------------------- # x-y平面投影曲线 fig.add_trace(go.Scatter3d( x=x, y=y, z=[350] * len(x), mode='lines', line=dict( color='black', width=5, ) )) # 原3D剖面曲线 fig.add_trace(go.Scatter3d( x=x, y=y, z=z, mode='lines', line=dict( color=color_attribute, width=13, colorscale='Jet', colorbar=dict( title=dict( text=colorbar_label, font=dict(size=14, color='black') ), thickness=20, len=0.6, tickfont=dict(size=12, color='black'), tickmode='linear', tickformat='.2f', outlinewidth=1, outlinecolor='black' ) ) )) # 垂直参考线(可选,可根据需要保留或删除) for i in range(0, len(x), 20): xi, yi, zi = x[i], y[i], z[i] fig.add_trace(go.Scatter3d( x=[xi, xi], y=[yi, yi], z=[350, zi], mode='lines', line=dict(color='dimgray', width=4), opacity=0.6, showlegend=False )) # 布局设置 fig.update_layout( template='plotly_white', scene=dict( xaxis=dict(title='Meters north from start position', showgrid=True, gridcolor='lightblue', zeroline=False), yaxis=dict(title='Meters east from start position', showgrid=True, gridcolor='lightblue', zeroline=False), zaxis=dict(title='Altitude [m]', showgrid=True, gridcolor='lightblue', zeroline=False), aspectmode='manual', aspectratio=dict(x=1.25, y=1, z=0.7) ), title=f'{colorbar_label}', margin=dict(l=0, r=0, b=0, t=50) ) fig.show() plot_3d_course_profile(x, y, z_min_adjusted, z_min_adjusted, 'Altitude [m]')
关键修改说明
- Mesh3d顶点构建:将原3D曲线的顶点和z=350的投影顶点拼接成一个数组,作为曲面的所有顶点。
- 三角面索引生成:遍历相邻顶点,为每一组四个顶点(上方两点+下方两点)生成两个三角面,确保曲面连续覆盖垂直区域。
- 曲面着色配置:使用
color参数绑定高度数据,配合colorscale实现渐变着色,调整opacity让曲面不会遮挡下方元素。
内容的提问来源于stack exchange,提问作者Márton Horváth
相关产品推荐
相关产品推荐

