下面的代码生成我测量强度的点的 3D 图。我希望将强度值附加到每个点,然后在点之间进行插值,以生成显示高强度和低强度点的彩色图/曲面图。
我相信这样做需要scipy.interpolate.RectBivariateSpline
,但我不确定它是如何工作的——因为我看过的例子都没有包含 3D 图。
编辑:我想将球体显示为曲面图,但我不确定我是否可以这样做,Axes3D
因为我的点分布不均匀(即赤道周围的点更靠近)
任何帮助将不胜感激。
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
# Radius of the sphere
r = 0.1648
# Our theta vals
theta = np.array([0.503352956, 1.006705913, 1.510058869,
1.631533785, 2.134886741, 2.638239697])
# Our phi values
phi = np.array([ np.pi/4, np.pi/2, 3*np.pi/4, np.pi,
5*np.pi/4, 3*np.pi/2, 7*np.pi/4, 2*np.pi])
# Loops over each angle to generate the points on the surface of sphere
def gen_coord():
x = np.zeros((len(theta), len(phi)), dtype=np.float32)
y = np.zeros((len(theta), len(phi)), dtype=np.float32)
z = np.zeros((len(theta), len(phi)), dtype=np.float32)
# runs over each angle, creating the x y z values
for i in range(len(theta)):
for j in range(len(phi)):
x[i,j] = r * np.sin(theta[i]) * np.cos(phi[j])
y[i,j] = r * np.sin(theta[i]) * np.sin(phi[j])
z[i,j] = r * np.cos(theta[i])
x_vals = np.reshape(x, 48)
y_vals = np.reshape(y, 48)
z_vals = np.reshape(z, 48)
return x_vals, y_vals, z_vals
# Plots the points on a 3d graph
def plot():
fig = plt.figure()
ax = fig.gca(projection='3d')
x, y, z = gen_coord()
ax.scatter(x, y, z)
plt.show()
编辑:更新:我已经格式化了我的数据数组(这里命名为 v),使得前 8 个值对应于 theta 的第一个值,依此类推。出于某种原因,与图表对应的颜色条表示我的电压为负值,原始代码中未显示。此外,输入的值似乎并不总是对应于应该是它们位置的点。我不确定是否存在某种偏移,或者我是否错误地解释了您的代码。
from scipy.interpolate import RectSphereBivariateSpline
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib.colorbar import ColorbarBase, make_axes_gridspec
r = 0.1648
theta = np.array([0.503352956, 1.006705913, 1.510058869, 1.631533785, 2.134886741, 2.638239697]) #Our theta vals
phi = np.array([np.pi/4, np.pi/2, 3*np.pi/4, np.pi, 5*np.pi/4, 3*np.pi/2, 7*np.pi/4, 2*np.pi]) #Our phi values
v = np.array([0.002284444388889,0.003155555477778,0.002968888844444,0.002035555555556,0.001884444411111,0.002177777733333,0.001279999988889,0.002666666577778,0.015777777366667,0.006053333155556,0.002755555533333,0.001431111088889,0.002231111077778,0.001893333311111,0.001288888877778,0.005404444355556,0,0.005546666566667,0.002231111077778,0.0032533332,0.003404444355556,0.000888888866667,0.001653333311111,0.006435555455556,0.015311110644444,0.002453333311111,0.000773333333333,0.003164444366667,0.035111109822222,0.005164444355556,0.003671111011111,0.002337777755556,0.004204444288889,0.001706666666667,0.001297777755556,0.0026577777,0.0032444444,0.001697777733333,0.001244444411111,0.001511111088889,0.001457777766667,0.002159999944444,0.000844444433333,0.000595555555556,0,0,0,0]) #Lists 1A-H, 2A-H,...,6A-H
volt = np.reshape(v, (6, 8))
spl = RectSphereBivariateSpline(theta, phi, volt)
# evaluate spline fit on a denser 50 x 50 grid of thetas and phis
theta_itp = np.linspace(0, np.pi, 100)
phi_itp = np.linspace(0, 2 * np.pi, 100)
d_itp = spl(theta_itp, phi_itp)
x_itp = r * np.outer(np.sin(theta_itp), np.cos(phi_itp)) #Cartesian coordinates of sphere
y_itp = r * np.outer(np.sin(theta_itp), np.sin(phi_itp))
z_itp = r * np.outer(np.cos(theta_itp), np.ones_like(phi_itp))
norm = plt.Normalize()
facecolors = plt.cm.jet(norm(d_itp))
# surface plot
fig, ax = plt.subplots(1, 1, subplot_kw={'projection':'3d', 'aspect':'equal'})
ax.hold(True)
ax.plot_surface(x_itp, y_itp, z_itp, rstride=1, cstride=1, facecolors=facecolors)
#Colourbar
cax, kw = make_axes_gridspec(ax, shrink=0.6, aspect=15)
cb = ColorbarBase(cax, cmap=plt.cm.jet, norm=norm)
cb.set_label('Voltage', fontsize='x-large')
plt.show()