径向 'sweep out' 2D 等高线图创建 3D 图(Python,Matplotlib)
Radially 'sweep out' a 2D contour plot to create a 3D plot (Python, Matplotlib)
我有三个一维数组,分别代表半径、高度和在该点测量的强度。我绘制了这些以创建二维等高线图。下面是数据存储方式的一个简单示例:
import numpy as np
import matplotlib.pyplot as plt
x = [1,1,1,2,2,2,3,3,3]
y = [1,2,3,1,2,3,1,2,3]
intensity = [5,6,8,9,9,11,15,5,2]
plt.xlabel('Radius')
plt.ylabel('Height')
plt.tricontourf(x,y,intensity)
plt.colorbar(label='Intensity')
plt.show()
(我不得不使用 plt.tricontourf 而不是 plt.contour,因为 z 数据不是二维的)
我希望通过 'sweeping' 360 度的 2D 图来创建 3D 图,创建一个方位角对称的圆盘。下图说明了我正在尝试做的事情...
...通过 360 度平滑插值的数据。
有几个类似的问题,特别是 this one,但这并没有使用三组数据来创建轮廓。
从技术上讲,您无法旋转 2D 图并获得 3D 表面。您只能旋转 2D 曲线并获得 3D 曲面。如果是这种情况,您可以这样做:
import numpy as np
from matplotlib import cm
import matplotlib.pyplot as plt
fig = plt.figure(figsize = (8, 6))
ax = fig.add_subplot(projection='3d')
N = 100
r = np.linspace(0, 1, N)
z = np.sqrt(1 - r**2)
intensity = np.linspace(0, 1, N).reshape(1, -1)
theta = np.linspace(0, 2*np.pi-1e-3, N)
X = np.outer(np.cos(theta), r)
Y = np.outer(np.sin(theta), r)
Z = np.repeat(z.reshape(1, -1), N, axis = 0)
surf = ax.plot_surface(X, Y, Z, facecolors=cm.jet(np.repeat(intensity, N, axis = 0)))
ax.axes.set_zlim3d(-1, 1)
plt.show()
在代码中,我旋转了一条曲线以创建半个单位球体并根据强度为其着色:
到
如果你坚持要绘制所有的点,我会建议一个 3d 散点图,我做了一些线性插值来显示比原来的 9 个更多的点:
from scipy.interpolate import interp2d
x = [1,1,1,2,2,2,3,3,3]
y = [1,2,3,1,2,3,1,2,3]
intensity = [5,6,8,9,9,11,15,5,2]
# number of points to interpolate in 3d space
N = 36
# number of points to interpolate in 2d space
N_2d = 10
f = interp2d(x, y, intensity)
# sample along the radius
r = np.linspace(1,3,N_2d)
# sample along z
z = np.linspace(1,3,N_2d)
intensity = f(r, z)
r,z = np.meshgrid(r, z)
theta = np.linspace(0, 2*np.pi, N)
X = np.outer(np.cos(theta), r)
Y = np.outer(np.sin(theta), r)
Z = np.repeat(z.reshape(1, -1), N, axis = 0)
fig = plt.figure(figsize = (10, 6))
ax = fig.add_subplot(projection='3d')
ax.scatter3D(X, Y, Z, c=np.tile(intensity.T, N).T, alpha = 0.5)
plt.show()
我有三个一维数组,分别代表半径、高度和在该点测量的强度。我绘制了这些以创建二维等高线图。下面是数据存储方式的一个简单示例:
import numpy as np
import matplotlib.pyplot as plt
x = [1,1,1,2,2,2,3,3,3]
y = [1,2,3,1,2,3,1,2,3]
intensity = [5,6,8,9,9,11,15,5,2]
plt.xlabel('Radius')
plt.ylabel('Height')
plt.tricontourf(x,y,intensity)
plt.colorbar(label='Intensity')
plt.show()
(我不得不使用 plt.tricontourf 而不是 plt.contour,因为 z 数据不是二维的)
我希望通过 'sweeping' 360 度的 2D 图来创建 3D 图,创建一个方位角对称的圆盘。下图说明了我正在尝试做的事情...
...通过 360 度平滑插值的数据。
有几个类似的问题,特别是 this one,但这并没有使用三组数据来创建轮廓。
从技术上讲,您无法旋转 2D 图并获得 3D 表面。您只能旋转 2D 曲线并获得 3D 曲面。如果是这种情况,您可以这样做:
import numpy as np
from matplotlib import cm
import matplotlib.pyplot as plt
fig = plt.figure(figsize = (8, 6))
ax = fig.add_subplot(projection='3d')
N = 100
r = np.linspace(0, 1, N)
z = np.sqrt(1 - r**2)
intensity = np.linspace(0, 1, N).reshape(1, -1)
theta = np.linspace(0, 2*np.pi-1e-3, N)
X = np.outer(np.cos(theta), r)
Y = np.outer(np.sin(theta), r)
Z = np.repeat(z.reshape(1, -1), N, axis = 0)
surf = ax.plot_surface(X, Y, Z, facecolors=cm.jet(np.repeat(intensity, N, axis = 0)))
ax.axes.set_zlim3d(-1, 1)
plt.show()
在代码中,我旋转了一条曲线以创建半个单位球体并根据强度为其着色:
到
如果你坚持要绘制所有的点,我会建议一个 3d 散点图,我做了一些线性插值来显示比原来的 9 个更多的点:
from scipy.interpolate import interp2d
x = [1,1,1,2,2,2,3,3,3]
y = [1,2,3,1,2,3,1,2,3]
intensity = [5,6,8,9,9,11,15,5,2]
# number of points to interpolate in 3d space
N = 36
# number of points to interpolate in 2d space
N_2d = 10
f = interp2d(x, y, intensity)
# sample along the radius
r = np.linspace(1,3,N_2d)
# sample along z
z = np.linspace(1,3,N_2d)
intensity = f(r, z)
r,z = np.meshgrid(r, z)
theta = np.linspace(0, 2*np.pi, N)
X = np.outer(np.cos(theta), r)
Y = np.outer(np.sin(theta), r)
Z = np.repeat(z.reshape(1, -1), N, axis = 0)
fig = plt.figure(figsize = (10, 6))
ax = fig.add_subplot(projection='3d')
ax.scatter3D(X, Y, Z, c=np.tile(intensity.T, N).T, alpha = 0.5)
plt.show()