使用mplot3d绘制凹面形状(镜头焦点)

时间:2018-02-08 16:53:18

标签: python matplotlib mplot3d

我目前正在尝试使用matplotlib可视化镜头的焦点形状,特别是mplot3d工具箱。我从适合椭圆到一组不同焦距的显微镜图像获得了数据,主要是major和次minor半径,以及所述椭圆的旋转角ang。据此,我正在生成包含椭圆坐标的xyz数组。

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()

Lines plot of ellipses

我要做的是从该数据集生成表面图,显示镜头的焦点形状。到目前为止,我和plot_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()

Surface plot of dataset using griddata

同样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()

Surface plot of dataset using trisurf

有人可以建议一种在表面图中正确显示数据集的高z区域的方法吗?

1 个答案:

答案 0 :(得分:2)

问题是您正在尝试在网格上插入参数曲线。由于绘制的形状是非双射的,非主观的,你会得到一个完整的混乱。

enter image description here

您可以直接绘制它们,而不是尝试插入点。

X = np.array(x)
Y = np.array(y)
Z = np.array(z)
ax.plot_surface(X,Y,Z, cmap="RdYlBu")
plt.show()

enter image description here

复制的完整示例:

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()