John Doe
John Doe

Reputation: 111

Plotting data on unit sphere with colours

Hi I have a data set of three columns: theta, phi and value of function at theta and phi. I want to project this data onto a unit sphere such that the colours on the sphere correspond to the magnitude of the function, in a similar sense to this post. The nature of the data which I provided a sample of, is that the values of the top half and bottom half of the sphere are identical, hence the expectation is that the colour distribution of the top and bottom half of the sphere would be identical, but for some reason I find that although the shape is correct, the top bottom half is brighter for some reason (see pics below). Does anyone know why this would be the case?

Dataset:

Theta     Phi      Values
0.000000 -3.141592 0.500000
0.000000 -3.078126 0.500000
0.000000 -3.014659 0.500000
...    ...  ...
0.031733 -3.141592 0.499497
0.031733 -3.078126 0.499497
0.031733 -3.014659 0.499497
...    ...  ...
0.507732 -0.031733 0.388763
0.507732  0.031734 0.388763
0.507732  0.095200 0.388541
...    ...  ...
1.364530 -0.095199 0.131597
1.364530 -0.031733 0.135245
1.364530 0.031734 0.135245
1.364530 0.095200 0.131597
...    ...  ...
2.633860 -0.095199 0.388541
2.633860 -0.031733 0.388763
2.633860  0.031734 0.388763
...    ...  ...    
3.109859 3.014660 0.499497
3.109859 3.078126 0.499497
3.109859 3.141593 0.499497
...    ...  ...
3.141592 3.014660 0.500000
3.141592 3.078126 0.500000
3.141592 3.141593 0.500000

Code:

from numpy import*
import math
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.cm as cm

#theta inclination angle
#phi azimuthal angle
n_theta = 100 #number of values for theta
n_phi = 100  #number of values for phi
r = 1        #radius of sphere

theta, phi = np.mgrid[0: pi:n_theta*1j,-pi:pi:n_phi*1j ]

x = r*np.sin(theta)*np.cos(phi)
y = r*np.sin(theta)*np.sin(phi)
z = r*np.cos(theta)

print theta.shape 
print phi.shape 

inp = []
f = open("datafile.dat","r")
for line in f:
    i = float(line.split()[0])
    j = float(line.split()[1])
    val = float(line.split()[2])
    inp.append([i, j, val])

inp = np.array(inp)
#print inp
#print inp.shape

#reshape the input array to the shape of the x,y,z arrays. 
c = inp[:,2].reshape((n_phi,n_theta))

#Set colours and render
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')

surf = ax.plot_surface(
    x,y,z,  rstride=1, cstride=1, facecolors=cm.hot(c), alpha=0.9, linewidth=1) 
ax.set_xlim([-2.0,2.0])
ax.set_ylim([-2.0,2.0])
ax.set_zlim([-2,2])
ax.set_aspect("equal")

plt.title('Projecting data on unit sphere')

#Label axis. 
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

#Creates array for colorbar from 0 to 1. 
a = array( [1.0, 0.5, 0.0])

#Creates colorbar
m = cm.ScalarMappable(cmap=cm.hot)
m.set_array(a)
plt.colorbar(m)
plt.savefig('Projecting data on unit sphere.png')

f.close()
plt.show()

enter image description here

Upvotes: 1

Views: 752

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339102

You need to set the plot_surface's shade argument to False,

ax.plot_surface(..., shade=False)

otherwise some light effects are simulated on top of your surface which will depend on the viewing angle.

Upvotes: 1

Related Questions