按距原点的距离着色点
Color point by distance from origin
这是在 Python 中使用 PyVista 创建的 Hopf 环面:
import numpy as np
import pyvista as pv
A = 0.44
n = 3
def Gamma(t):
alpha = np.pi/2 - (np.pi/2-A)*np.cos(n*t)
beta = t + A*np.sin(2*n*t)
return np.array([
np.sin(alpha) * np.cos(beta),
np.sin(alpha) * np.sin(beta),
np.cos(alpha)
])
def HopfInverse(p, phi):
return np.array([
(1+p[2])*np.cos(phi),
p[0]*np.sin(phi) - p[1]*np.cos(phi),
p[0]*np.cos(phi) + p[1]*np.sin(phi),
(1+p[2])*np.sin(phi)
]) / np.sqrt(2*(1+p[2]))
def Stereo(q):
return 2*q[0:3] / (1-q[3])
def F(t, phi):
return Stereo(HopfInverse(Gamma(t), phi))
angle = np.linspace(0, 2*np.pi, 300)
angle2 = np.linspace(0, np.pi, 150)
theta, phi = np.meshgrid(angle, angle2)
x, y, z = F(theta, phi)
# Display the mesh
grid = pv.StructuredGrid(x, y, z)
grid.plot(smooth_shading=True)
我想为这个表面添加一个调色板。环面以原点 (0,0,0) 为中心。我想要一种颜色与原点距离的函数。
使用 Matplotlib,我做:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.colors as mcolors
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np
A = 0.44
n = 3
......
colorfunction = (X**2+Y**2+Z**2)
norm = mcolors.Normalize(colorfunction.min(),colorfunction.max())
# Display the mesh
fig = plt.figure()
ax = fig.gca(projection = '3d')
ax.plot_surface(z, x, y, rstride = 1, cstride = 1, facecolors=cm.jet(norm(colorfunction)))
plt.show()
编辑
我有一个解决方案,但我无法控制颜色:
grid = pv.StructuredGrid(x, y, z)
grid['Data'] = grid.points
grid.plot(smooth_shading=True, scalars="Data")
作为旁注,至少对我来说,自己计算点的大小并将它们设置为标量(而不是依赖矢量数据的大小作为颜色映射的标量,即使这是支持的有效)。
你缺少的只是a choice of colourmap。与 matplotlib 一样,默认值是 viridis
。相反,您似乎想要 jet
(尽管我不建议这样做;在大多数情况下,对于数据可视化而言,感知统一的颜色映射更可取):
import numpy as np
import pyvista as pv
A = 0.44
n = 3
def Gamma(t):
alpha = np.pi/2 - (np.pi/2-A)*np.cos(n*t)
beta = t + A*np.sin(2*n*t)
return np.array([
np.sin(alpha) * np.cos(beta),
np.sin(alpha) * np.sin(beta),
np.cos(alpha)
])
def HopfInverse(p, phi):
return np.array([
(1+p[2])*np.cos(phi),
p[0]*np.sin(phi) - p[1]*np.cos(phi),
p[0]*np.cos(phi) + p[1]*np.sin(phi),
(1+p[2])*np.sin(phi)
]) / np.sqrt(2*(1+p[2]))
def Stereo(q):
return 2*q[0:3] / (1-q[3])
def F(t, phi):
return Stereo(HopfInverse(Gamma(t), phi))
angle = np.linspace(0, 2 * np.pi, 300)
theta, phi = np.meshgrid(angle, angle)
x, y, z = F(theta, phi)
grid = pv.StructuredGrid(x, y, z)
# convert to PolyData and clean to remove the seam
cleaned_poly = grid.extract_geometry().clean(tolerance=1e-6)
# add distance from origin as scalars
cleaned_poly.point_data['distance'] = np.linalg.norm(cleaned_poly.points, axis=1)
# this also makes these the default scalars
cleaned_poly.plot(smooth_shading=True, cmap='jet') # but don't use jet if possible
这是在 Python 中使用 PyVista 创建的 Hopf 环面:
import numpy as np
import pyvista as pv
A = 0.44
n = 3
def Gamma(t):
alpha = np.pi/2 - (np.pi/2-A)*np.cos(n*t)
beta = t + A*np.sin(2*n*t)
return np.array([
np.sin(alpha) * np.cos(beta),
np.sin(alpha) * np.sin(beta),
np.cos(alpha)
])
def HopfInverse(p, phi):
return np.array([
(1+p[2])*np.cos(phi),
p[0]*np.sin(phi) - p[1]*np.cos(phi),
p[0]*np.cos(phi) + p[1]*np.sin(phi),
(1+p[2])*np.sin(phi)
]) / np.sqrt(2*(1+p[2]))
def Stereo(q):
return 2*q[0:3] / (1-q[3])
def F(t, phi):
return Stereo(HopfInverse(Gamma(t), phi))
angle = np.linspace(0, 2*np.pi, 300)
angle2 = np.linspace(0, np.pi, 150)
theta, phi = np.meshgrid(angle, angle2)
x, y, z = F(theta, phi)
# Display the mesh
grid = pv.StructuredGrid(x, y, z)
grid.plot(smooth_shading=True)
我想为这个表面添加一个调色板。环面以原点 (0,0,0) 为中心。我想要一种颜色与原点距离的函数。
使用 Matplotlib,我做:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.colors as mcolors
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np
A = 0.44
n = 3
......
colorfunction = (X**2+Y**2+Z**2)
norm = mcolors.Normalize(colorfunction.min(),colorfunction.max())
# Display the mesh
fig = plt.figure()
ax = fig.gca(projection = '3d')
ax.plot_surface(z, x, y, rstride = 1, cstride = 1, facecolors=cm.jet(norm(colorfunction)))
plt.show()
编辑
我有一个解决方案,但我无法控制颜色:
grid = pv.StructuredGrid(x, y, z)
grid['Data'] = grid.points
grid.plot(smooth_shading=True, scalars="Data")
作为旁注,至少对我来说,自己计算点的大小并将它们设置为标量(而不是依赖矢量数据的大小作为颜色映射的标量,即使这是支持的有效)。
你缺少的只是a choice of colourmap。与 matplotlib 一样,默认值是 viridis
。相反,您似乎想要 jet
(尽管我不建议这样做;在大多数情况下,对于数据可视化而言,感知统一的颜色映射更可取):
import numpy as np
import pyvista as pv
A = 0.44
n = 3
def Gamma(t):
alpha = np.pi/2 - (np.pi/2-A)*np.cos(n*t)
beta = t + A*np.sin(2*n*t)
return np.array([
np.sin(alpha) * np.cos(beta),
np.sin(alpha) * np.sin(beta),
np.cos(alpha)
])
def HopfInverse(p, phi):
return np.array([
(1+p[2])*np.cos(phi),
p[0]*np.sin(phi) - p[1]*np.cos(phi),
p[0]*np.cos(phi) + p[1]*np.sin(phi),
(1+p[2])*np.sin(phi)
]) / np.sqrt(2*(1+p[2]))
def Stereo(q):
return 2*q[0:3] / (1-q[3])
def F(t, phi):
return Stereo(HopfInverse(Gamma(t), phi))
angle = np.linspace(0, 2 * np.pi, 300)
theta, phi = np.meshgrid(angle, angle)
x, y, z = F(theta, phi)
grid = pv.StructuredGrid(x, y, z)
# convert to PolyData and clean to remove the seam
cleaned_poly = grid.extract_geometry().clean(tolerance=1e-6)
# add distance from origin as scalars
cleaned_poly.point_data['distance'] = np.linalg.norm(cleaned_poly.points, axis=1)
# this also makes these the default scalars
cleaned_poly.plot(smooth_shading=True, cmap='jet') # but don't use jet if possible