基于自由分布3D点数据生成2D截面图的Python技术求助
解决方案:基于散点数据生成3D曲面及截面图
数据说明
原始测量数据为无规则分布的(x,y,z)散点,存储在Pandas DataFrame中:
Node [-] x [m] y [m] eps_xx [-] 0 1 0.0096 0.0089 8.310000e-07 1 2 0.0000 0.0089 1.317000e-07 2 3 0.0000 0.0000 8.104000e-07 3 4 0.0096 0.0000 2.465000e-06 4 5 0.0192 0.0000 6.276000e-06 ... ... ... ... ... 2314 2315 0.7700 0.1333 -7.269000e-06 2315 2316 0.7700 0.1426 -6.697000e-06 2316 2317 0.7700 0.1499 -3.587000e-06 2317 2318 0.7700 0.1520 6.296000e-07 2318 2319 0.7700 0.1600 -2.000000e-06
现有散点图代码
import pandas as pd import plotly.graph_objects as go # 读取数据 df = pd.read_excel('Data.xlsx', sheet_name="Step_5") # 提取坐标与测量值 x = df['x [m]'].values y = df['y [m]'].values z = df['eps_xx [-]'].values # 绘制3D散点图 fig = go.Figure() fig.add_trace(go.Scatter3d(x=x, y=y, z=z, mode='markers', marker=dict(size=3))) fig.update_layout(scene=dict(xaxis_title='x [m]', yaxis_title='y [m]', zaxis_title='eps_xx [-]')) fig.show()
针对问题的解决方案
1. 生成3D曲面图(基于插值)
Plotly的go.Surface需要规则网格数据,因此先用线性插值将散点转换为规则网格:
import numpy as np from scipy.interpolate import griddata # 1. 生成规则网格 # 定义网格分辨率(数值越小,曲面越精细) grid_res = 0.01 # 获取x、y的取值范围 x_min, x_max = x.min(), x.max() y_min, y_max = y.min(), y.max() # 生成网格点 xi = np.arange(x_min, x_max, grid_res) yi = np.arange(y_min, y_max, grid_res) xi, yi = np.meshgrid(xi, yi) # 2. 线性插值得到网格上的z值 zi = griddata((x, y), z, (xi, yi), method='linear') # 3. 绘制3D曲面图 fig = go.Figure() # 添加曲面层 fig.add_trace(go.Surface(x=xi, y=yi, z=zi, colorscale='Viridis', opacity=0.8)) # 叠加原始散点(可选,用于对比) fig.add_trace(go.Scatter3d(x=x, y=y, z=z, mode='markers', marker=dict(size=3, color='black'))) fig.update_layout(scene=dict(xaxis_title='x [m]', yaxis_title='y [m]', zaxis_title='eps_xx [-]')) fig.show()
2. 生成指定垂直平面的截面图
以x=0.5m的垂直平面为例,提取该平面数据并绘制2D图:
# 1. 提取指定截面的数据 target_x = 0.5 # 找到最接近目标x值的网格列 x_col_idx = np.argmin(np.abs(xi[0] - target_x)) # 获取该截面的y和z值 section_y = yi[:, x_col_idx] section_z = zi[:, x_col_idx] # 过滤插值产生的NaN无效值 valid_mask = ~np.isnan(section_z) section_y = section_y[valid_mask] section_z = section_z[valid_mask] # 2. 保存截面数据到Pandas DataFrame section_df = pd.DataFrame({ 'y [m]': section_y, 'eps_xx [-]': section_z }) # 可选:保存到本地Excel section_df.to_excel('section_data.xlsx', index=False) # 3. 绘制2D截面图 fig = go.Figure() fig.add_trace(go.Scatter(x=section_y, y=section_z, mode='lines+markers')) fig.update_layout( title=f'截面图 (x={target_x}m)', xaxis_title='y [m]', yaxis_title='eps_xx [-]' ) fig.show()
3. 其他截面类型(如固定y值)
若需要沿固定y值的垂直截面,修改索引提取逻辑即可:
target_y = 0.1 # 找到最接近目标y值的网格行 y_row_idx = np.argmin(np.abs(yi[:,0] - target_y)) # 获取该截面的x和z值 section_x = xi[y_row_idx, :] section_z = zi[y_row_idx, :] # 过滤无效值 valid_mask = ~np.isnan(section_z) section_x = section_x[valid_mask] section_z = section_z[valid_mask] # 保存到DataFrame section_df = pd.DataFrame({ 'x [m]': section_x, 'eps_xx [-]': section_z })
内容的提问来源于stack exchange,提问作者Thanksalot
相关产品推荐
相关产品推荐

