I want to plot 3D antenna radiation pattern from CSV file, after data loading i have got:
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
so Theta chages from 0 to 180 deg, and Phi 0 to 355. Then i run code:
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)
Here are plots.
What I have from python script:
and
From x-y side:
(from 'top') we can see that there is no smooth connection between values, but sphere back to (0, 0, 0) point.
The proper radiation pattern:
How to solve this?
I think that you are just getting row/column order muddled up (multiple times). Theta changes fastest in your input.
Note that you will also get a small gap in your plot unless your input data file includes the full-circle value for phi=360 degrees at the end.
I don't have your data, so I had to generate my own (see the Fortran program at the bottom of the post - its much simpler than your actual data). However, see if this solution works for your file.
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')
# Separate columns
theta1d = np.array( df['Theta'] )
phi1d = np.array( df['Phi'] )
dir1d = np.array( df['Dir'] )
# Reshape for plot. NOTE: theta varies fastest in your input file
angle_count_theta = len( np.unique( theta1d ) )
angle_count_phi = len( np.unique( phi1d ) )
theta2d = theta1d.reshape( [ angle_count_phi, angle_count_theta ] )
phi2d = phi1d .reshape( [ angle_count_phi, angle_count_theta ] )
R = np.empty ( ( angle_count_phi, angle_count_theta ) )
for i in range( angle_count_phi ):
for j in range( angle_count_theta ):
R[i,j] = dir1d[ i * angle_count_theta + j ]
THETA = np.deg2rad(theta2d)
PHI = np.deg2rad(phi2d)
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)
Output:
Some data generation:
program test
implicit none
real, parameter :: PI = 4.0 * atan( 1.0 )
integer nphi, ntheta
integer i, j
real theta, phi, z
real dtheta, dphi
nphi = 73; ntheta = 37
dphi = 360.0 / ( nphi - 1 )
dtheta = 180.0 / ( ntheta - 1 )
open( 10, file="output_file.csv" )
write( 10, "( a, ',', a, ',', a )" ) "Theta", "Phi", "Dir"
do j = 0, nphi - 1
phi = j * dphi
do i = 0, ntheta - 1
theta = i * dtheta
z = 10.0 * ( 1 + cos( theta * PI / 180.0 ) )
write( 10, "( 1x, f7.2, ',', f7.2, ',', f7.2 )" ) theta, phi, z
end do
end do
close( 10 )
end program test