Python 使用mplot3d绘制凹面形状(镜头焦点)
我目前正在尝试使用matplotlib可视化镜头的焦距形状,特别是mplot3d工具箱。我获得了将椭圆拟合到一组不同焦距的显微镜图像上的数据,这些图像的焦距分别为:大Python 使用mplot3d绘制凹面形状(镜头焦点),python,matplotlib,mplot3d,Python,Matplotlib,Mplot3d,我目前正在尝试使用matplotlib可视化镜头的焦距形状,特别是mplot3d工具箱。我获得了将椭圆拟合到一组不同焦距的显微镜图像上的数据,这些图像的焦距分别为:大major和小minor半径,以及所述椭圆的旋转角度ang。由此,我将生成包含椭圆坐标的x、y和z数组,如下图所示 i = 100 omega = np.linspace(0, 2 * np.pi, i, endpoint=True) x = [major * np.cos(omega) * np.cos(np.deg2rad(a
major
和小minor
半径,以及所述椭圆的旋转角度ang
。由此,我将生成包含椭圆坐标的x
、y
和z
数组,如下图所示
i = 100
omega = np.linspace(0, 2 * np.pi, i, endpoint=True)
x = [major * np.cos(omega) * np.cos(np.deg2rad(ang + 90)) - minor * np.sin(omega) * np.sin(np.deg2rad(ang + 90)) for major, minor, ang in zip(maj_avg, min_avg, ang_avg)]
y = [major * np.cos(omega) * np.sin(np.deg2rad(ang + 90)) + minor * np.sin(omega) * np.cos(np.deg2rad(ang + 90)) for major, minor, ang in zip(maj_avg, min_avg, ang_avg)]
z = [np.full(i, zi) for zi in zs]
如果我现在在3D空间中绘制单个椭圆,一切都会按预期进行
fig = plt.figure(figsize=(16, 12))
ax = fig.add_subplot(111, projection='3d')
for x_arr, y_arr, z_arr in zip(x, y, z):
ax.plot(x_arr, y_arr, z_arr)
plt.show()
我要做的是从这个数据集生成一个曲面图,显示镜头的焦点形状。到目前为止,我尝试了plot\u surface
和meshgrid
/griddata
如下:
xi = np.arange(-300, 300, 0.1)
yi = np.arange(-300, 300, 0.1)
xgrid, ygrid = np.meshgrid(xi, yi)
zgrid = griddata(np.ravel(x), np.ravel(y), np.ravel(z), xi, yi, interp='linear')
fig = plt.figure(figsize=(16, 12))
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(xgrid, ygrid, zgrid)
plt.show()
而且,plot_trisurf
也给出了同样不令人满意的结果:
triang = mtri.Triangulation(np.ravel(x), np.ravel(y))
fig = plt.figure(figsize=(16, 12))
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(triang, np.ravel(z), cmap=plt.cm.CMRmap)
plt.show()
有人能建议一种在曲面图中正确显示我的数据集的高z区域的方法吗?问题是您试图在网格上插值参数曲线。由于要绘制的形状是一个非双射的、非单射的形状,因此会得到一个完全混乱的形状 您可以直接绘制点,而不是尝试插值点
X = np.array(x)
Y = np.array(y)
Z = np.array(z)
ax.plot_surface(X,Y,Z, cmap="RdYlBu")
plt.show()
复制的完整示例:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
maj_avg = 50*(np.linspace(0,1,20)-0.6)**2+50
min_avg = 60*(np.linspace(0,1,20)-0.7)**2+60
ang_avg = np.linspace(0,90,20)
zs = np.arange(0,40,2)
i = 100
omega = np.linspace(0, 2 * np.pi, i, endpoint=True)
x = [major * np.cos(omega) * np.cos(np.deg2rad(ang + 90)) \
- minor * np.sin(omega) * np.sin(np.deg2rad(ang + 90)) \
for major, minor, ang in zip(maj_avg, min_avg, ang_avg)]
y = [major * np.cos(omega) * np.sin(np.deg2rad(ang + 90)) \
+ minor * np.sin(omega) * np.cos(np.deg2rad(ang + 90)) \
for major, minor, ang in zip(maj_avg, min_avg, ang_avg)]
z = [np.full(i, zi) for zi in zs]
fig = plt.figure(figsize=(16, 12))
ax = fig.add_subplot(111, projection='3d')
#for x_arr, y_arr, z_arr in zip(x, y, z):
# ax.plot(x_arr, y_arr, z_arr)
X = np.array(x)
Y = np.array(y)
Z = np.array(z)
ax.plot_surface(X,Y,Z, cmap="RdYlBu")
plt.show()
如果您有这样的问题,首先创建一个。这里的问题是,您试图在栅格上插值参数曲线。有什么原因吗?为什么不采用数据点本身?您的问题可能是由于插值,边界区域中存在NaN值吗?例如,请参见。@Piintesky不,问题很简单,当尝试在网格上插值一个非双射、非单射函数时,您将不可避免地得到一个。谢谢,这解决了问题。我想我没有这样做,因为在中,它说X,Y,Z必须作为2D数组提供,我假设我只能通过使用griddata获得。