我想将720 x 180的theta和phi值绘制成 θ范围=(-180到180,步长为0.5) phi range =(0到-90,步长为0.5)
这是我拥有的数据集示例:
Theta Phi Values
-180 0 0.2
-180 0.5 0.5
... ... ...
-180 -90 1.1
-179.5 0 0.92
... ... ...
0 -90 0.6
... ... ...
180 -89.5 0.17
180 -90 0.12
所以最终,我想得到一个类似这样的情节:
我知道如何使用下面的代码创建半球,但是如何从我的数据框中分配值?
import matplotlib.pyplot as plt
from matplotlib import cm, colors
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
# Create a sphere
r = 2
pi = np.pi
cos = np.cos
sin = np.sin
altitude
phi, theta = np.mgrid[0.0:0.5*pi:180j, 0.0:2.0*pi:720j] # phi = alti, theta = azi
x = r*sin(phi)*cos(theta)
y = r*sin(phi)*sin(theta)
z = r*cos(phi)
#Set colours and render
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(
x, y, z, rstride=4, cstride=4, color='w', alpha=0.1, linewidth=0)
ax.set_xlim([-2.2,2.2])
ax.set_ylim([-2.2,2.2])
ax.set_zlim([0,3])
ax.set_aspect("equal")
ax.plot_wireframe(x, y, z, color="k")
代码生成这个
答案 0 :(得分:3)
Axes3D.plot_surface
接受2D数组作为输入。它提供facecolors
参数,该参数接受与输入数组形状相同的数组。这个数组应该将每个面的颜色作为rgba元组。因此,可以将数组值标准化为最大1的范围,并为其提供matplotlib.cm
的色彩映射。
剩下的问题是从提供的3列列表中获取此数组。给定长度为n*m
的数据表,其中第一列表示x
值,第二列表示y
值,第三列表示值,以及排序首先由x
表示的位置按y
。然后,可以使用(n,m)
将最后一列重新整形为n
数组,其中x
是m
值和.reshape((m,n)).T
y值的数量。< / p>
进一步评论:
plot_wireframe
可能没有多大意义,因为它会隐藏下面的表面。如果需要线框,可以使用要绘制的点数和linewidth
关键字参数。将linewidth
设置为大的,如3或5,使表面看起来不错,将其设置为1会留下一些线框外观。这是完整的解决方案。
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
#theta inclination angle
#phi azimuthal angle
n_theta = 50 # number of values for theta
n_phi = 200 # number of values for phi
r = 2 #radius of sphere
theta, phi = np.mgrid[0.0:0.5*np.pi:n_theta*1j, 0.0:2.0*np.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)
# mimic the input array
# array columns phi, theta, value
# first n_theta entries: phi=0, second n_theta entries: phi=0.0315..
inp = []
for j in phi[0,:]:
for i in theta[:,0]:
val = 0.7+np.cos(j)*np.sin(i+np.pi/4.)# put something useful here
inp.append([j, i, val])
inp = np.array(inp)
print inp.shape
print inp[49:60, :]
#reshape the input array to the shape of the x,y,z arrays.
c = inp[:,2].reshape((n_phi,n_theta)).T
print z.shape
print c.shape
#Set colours and render
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
#use facecolors argument, provide array of same shape as z
# cm.<cmapname>() allows to get rgba color from array.
# array must be normalized between 0 and 1
ax.plot_surface(
x,y,z, rstride=1, cstride=1, facecolors=cm.hot(c/c.max()), alpha=0.9, linewidth=1)
ax.set_xlim([-2.2,2.2])
ax.set_ylim([-2.2,2.2])
ax.set_zlim([0,4.4])
ax.set_aspect("equal")
#ax.plot_wireframe(x, y, z, color="k") #not needed?!
plt.savefig(__file__+".png")
plt.show()