Python 使用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

我目前正在尝试使用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(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获得。