'Python, Spherical Plot- Color Scaling

I'm pretty new with python. For the past two days I have been trying to figure out how to scale the color of a 3d plot (Antenna Radiation Pattern) with matplotlib. It looks like the scaling works in one of the xyz axis, but not when the scaling goes from the origin (radius). Any help is very appreciated.

It's not my code, but i found it very useful.

This is the code:

  • The values ​​are read from an excel document

  • As you can see I'm trying to play around with this command colors=plt.cm.jet((R)/(Rmax)), but it's not working.

              import pandas as pd
              import numpy as np
              import matplotlib.pyplot as plt
              import mpl_toolkits.mplot3d.axes3d as axes3d
    
              # Read data file and plot
              df = pd.read_csv('EIRP_Data.csv') #henter data fra Excel
    
              theta1d = df['Theta']                  
              theta1d = np.array(theta1d);
              theta2d = theta1d.reshape([37,73]) #"Theta" kolonen blir hentet ut, satt i numpy array og gjort om til 2d array
    
              phi1d = df['Phi']
              phi1d = np.array(phi1d);
              phi2d = phi1d.reshape([37,73]) #"Phi" kolonen blir hentet ut, satt i numpy array og gjort om til 2d Array
    
              power1d = df['Power']
              power1d = np.array(power1d);
              power2d = power1d.reshape([37,73]) #"Power" kolonen blir hentet ut, satt i numpy array og gjort om til 2d array
    
              THETA = np.deg2rad(theta2d)
              PHI = np.deg2rad(phi2d)
              R = power2d
              Rmax = np.max(R)
              Rmin = np.min(R)
              N = R / Rmax
    
              #Gjør om polar til kartesisk
              X = R * np.sin(THETA) * np.cos(PHI) 
              Y = R * np.sin(THETA) * np.sin(PHI)
              Z = R * np.cos(THETA)
    
              fig = plt.figure()
    
              #plot spesifikasjoner/settings
              ax = fig.add_subplot(1,1,1, projection='3d') 
              ax.grid(True)
              ax.axis('on')
              ax.set_xlabel('X')
              ax.set_ylabel('Y')
              ax.set_zlabel('Z')
              ax.set_xticklabels([]) 
              ax.set_yticklabels([])
              ax.set_zticklabels([])
    
              #colors =plt.cm.jet( (X.max()-X)/float((X-X.min()).max()))
              colors =plt.cm.jet( (R)/(Rmax) )
              ax.plot_surface(
                  X, Y, Z, rstride=1, cstride=1, facecolors=colors,
                  linewidth=0, antialiased=True, alpha=0.5, zorder = 0.5)
    
              ax.view_init(azim=300, elev = 30)
    
              # Add Spherical Grid
              phi ,theta = np.linspace(0, 2 * np.pi, 40), np.linspace(0, np.pi, 40)
              PHI, THETA  = np.meshgrid(phi,theta)
              R = Rmax
              X = R * np.sin(THETA) * np.cos(PHI)
              Y = R * np.sin(THETA) * np.sin(PHI)
              Z = R * np.cos(THETA)
    
              ax.plot_wireframe(X, Y, Z, linewidth=0.5, rstride=20, cstride=20)
    
              plt.show()
    

urrent plot



Solution 1:[1]

I have the following code to consider the radius for the color scale. The thing that did the trick was using a colormap to get the color values for the normalized R (here color-weights).

X = np.ones((phiSize, thetaSize))                                                                           # Prepare arrays to hold the cartesian coordinate data.
Y = np.ones((phiSize, thetaSize))
Z = np.ones((phiSize, thetaSize))
color_weight = np.ones((phiSize, thetaSize))

min_dBi = np.abs(df["dBi"].min())

for phi_idx, phi in enumerate(np.unique(df["Phi"])):
    for theta_idx, theta in enumerate(np.unique(df["Theta"])):
        e = df.query(f"Phi=={phi} and Theta=={theta}").iloc[0]["dBi"]
        e = min_dBi + e # so we dont have any negative numbers
        xe, ye, ze = sph2cart1(e, math.radians(theta), math.radians(phi))                                   # Calculate cartesian coordinates

        X[phi_idx, theta_idx] = xe                                                                                  # Store cartesian coordinates
        Y[phi_idx, theta_idx] = ye
        Z[phi_idx, theta_idx] = ze
        color_weight[phi_idx, theta_idx] = e

ax.plot_surface(X, Y, Z, color='b')                                                                         # Plot surface
plt.ylabel('Y')
plt.xlabel('X')                                                                                             # Plot formatting
plt.show()

with phisizeand thetaSize the number of unique phis and thetas in my data. The dBi of my antenna was stored in a pandas in the dBi column.

Solution 2:[2]

I can't see the dataset but i think all about tuples. If you delete "facecolors=colors" in plot_surface and then replace this: cmap=plt.get_cmap('jet') I think the problem will be solved.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 gillesC
Solution 2 ozzyys