3D antenna radiation plot in spherical coorinates problem

74 Views Asked by At

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:

what i have from python script

and

From x-y side:

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:

The proper radiation pattern

How to solve this?

1

There are 1 best solutions below

4
lastchance On BEST ANSWER

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:

enter image description here

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