You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复CSV数据绘制的3D天线辐射图连接不光滑问题

问题

从CSV文件加载天线辐射方向图数据,格式如下:

Theta    Phi     Dir
0       0.000    0.0   8.272
1       5.000    0.0   8.221
2      10.000    0.0   8.064
3      15.000    0.0   7.804
4      20.000    0.0   7.444
...       ...    ...     ...
2659  160.000  355.0 -13.240
2660  165.000  355.0 -12.330
2661  170.000  355.0 -11.460
2662  175.000  355.0 -10.870
2663  180.000  355.0 -10.670

Theta范围0°至180°,Phi范围0°至355°。运行以下Python代码绘制3D图后,出现数值间连接不光滑、曲面回退至(0,0,0)点的问题:

import pandas as pd
import numpy as np
from array import *
import numpy as np
import pandas as pd
import plotly.graph_objects as go
from plotly.offline import plot

# Read data from CSV file
df = pd.read_csv('output_file.csv')


# reshaping data for plot
theta1d = df['Theta']                  
theta1d = np.array(theta1d)
theta1d_unique = np.unique(theta1d)

angle_count_theta = len(theta1d_unique)

phi1d = df['Phi']                  
phi1d = np.array(phi1d)
phi1d_unique = np.unique(phi1d)

angle_count_phi = len(phi1d_unique)


theta2d = theta1d.reshape([angle_count_theta, angle_count_phi])
phi2d = phi1d.reshape([angle_count_theta, angle_count_phi])

dir1d = df['Dir']                  
dir1d = np.array(dir1d)


R = np.empty((angle_count_theta, angle_count_phi))
row_count = 0

for j in range(angle_count_phi):
    for i in range(angle_count_theta):
        R[i,j] = dir1d[row_count * angle_count_theta + i]
    row_count += 1
    
THETA = np.deg2rad(theta2d)
PHI = np.deg2rad(phi2d)

THETA = THETA.reshape(R.shape[0],R.shape[1])
PHI = PHI.reshape(R.shape[0],R.shape[1])

# transformation of spherical data 

X = R * np.sin(THETA) * np.cos(PHI) 
Y = R * np.sin(THETA) * np.sin(PHI)
Z = R * np.cos(THETA)


min_X = np.min(X)
max_X = np.max(X)
min_Y = np.min(Y)
max_Y = np.max(Y)

layout = go.Layout(title="3D Radiation Pattern of 5G CW data", xaxis = dict(range=[min_X,max_X],), yaxis = dict(range=[min_Y,max_Y],))

fig = go.Figure(data=[go.Surface(x=X, y=Y, z=Z, surfacecolor=R, colorscale='mygbm', colorbar = dict(title = "Gain", thickness = 50, xpad = 500))], layout = layout)

fig.update_layout(autosize = True, margin = dict(l = 50, r = 50, t = 250, b = 250))

plot(fig)
解决方案

问题根源分析

  1. 数据重塑错误:手动填充R矩阵时索引计算逻辑有误,导致数据排列混乱,曲面连接错位。
  2. Phi角度不闭合:数据中Phi仅到355°,缺少360°(等价于0°)的重复数据,Plotly无法闭合曲面,出现回退原点的问题。
  3. 冗余代码干扰:重复导入库、无效的reshape操作增加代码复杂度,容易引发逻辑错误。

修复步骤

1. 正确生成二维R矩阵

用Pandas的pivot方法直接映射(Theta, Phi)与Dir的对应关系,避免手动循环的索引错误:

# 替换原代码中手动填充R的部分
pivot_df = df.pivot(index='Theta', columns='Phi', values='Dir')
R = pivot_df.values
theta1d_unique = pivot_df.index.values
phi1d_unique = pivot_df.columns.values
THETA = np.deg2rad(theta1d_unique)[:, np.newaxis]  # 转为列向量实现广播
PHI = np.deg2rad(phi1d_unique)[np.newaxis, :]      # 转为行向量实现广播

2. 闭合Phi角度范围

复制Phi=0°的行并将Phi改为360°,让角度形成闭合环:

# 在读取CSV后添加此代码
phi_0_row = df[df['Phi'] == 0.0].copy()
phi_0_row['Phi'] = 360.0
df = pd.concat([df, phi_0_row], ignore_index=True)

3. 优化绘图参数与代码结构

  • 移除冗余导入语句,简化代码。
  • 将原2D布局参数替换为3D场景的scene配置,适配3D图的轴设置。
  • 添加contours参数提升曲面光滑度。

完整修复后代码

import pandas as pd
import numpy as np
import plotly.graph_objects as go
from plotly.offline import plot

# 读取数据并闭合Phi角度
df = pd.read_csv('output_file.csv')
phi_0_row = df[df['Phi'] == 0.0].copy()
phi_0_row['Phi'] = 360.0
df = pd.concat([df, phi_0_row], ignore_index=True)

# 生成二维R矩阵
pivot_df = df.pivot(index='Theta', columns='Phi', values='Dir')
R = pivot_df.values
theta_rad = np.deg2rad(pivot_df.index.values)[:, np.newaxis]
phi_rad = np.deg2rad(pivot_df.columns.values)[np.newaxis, :]

# 球坐标转笛卡尔坐标
X = R * np.sin(theta_rad) * np.cos(phi_rad)
Y = R * np.sin(theta_rad) * np.sin(phi_rad)
Z = R * np.cos(theta_rad)

# 3D场景布局设置
layout = go.Layout(
    title="3D Radiation Pattern of 5G CW data",
    scene=dict(
        xaxis_title='X',
        yaxis_title='Y',
        zaxis_title='Z',
        aspectmode='data'
    ),
    autosize=True,
    margin=dict(l=50, r=50, t=100, b=50)
)

# 绘制光滑曲面
fig = go.Figure(data=[go.Surface(
    x=X, y=Y, z=Z,
    surfacecolor=R,
    colorscale='Viridis',
    colorbar=dict(title="Gain", thickness=50),
    contours=dict(
        z=dict(show=True, usecolormap=True, highlightcolor="#42f462", project_z=True)
    )
)], layout=layout)

plot(fig)

额外光滑度优化

若数据点间距较大,可通过插值生成更密集的网格:

from scipy.interpolate import griddata

# 生成高密度角度网格
theta_dense = np.linspace(0, 180, 72)
phi_dense = np.linspace(0, 360, 72)
theta_grid, phi_grid = np.meshgrid(theta_dense, phi_dense)

# 三次插值获取平滑的Dir值
points = df[['Theta', 'Phi']].values
values = df['Dir'].values
R_dense = griddata(points, values, (theta_grid, phi_grid), method='cubic')

# 后续用R_dense进行坐标转换和绘图即可

内容的提问来源于stack exchange,提问作者Chey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 23:25:58