matplotlib 3D 数据的 2D 切片

Posted

技术标签:

【中文标题】matplotlib 3D 数据的 2D 切片【英文标题】:matplotlib 2D slice of 3D data 【发布时间】:2016-10-19 10:49:19 【问题描述】:

我在这方面找不到任何东西,可能是因为我没有正确的命名法(即我不知道确切如何要求它),但无论如何,我有一个 3D numpy 数组“一种”。我想识别并绘制 a=0 的二维曲面。为了清楚起见,数据是在 3D 空间上平滑变化的双精度浮点数。曲面 a=0 很可能会在数组的点之间“穿线”,而不是完全位于其中的任何点上。所以我需要一些可以插值的东西来找到 a=0 表面并绘制它。 matplotlib 是否有现成的例程来执行此操作?

【问题讨论】:

这似乎更像是一个 numpy 或 scipy 的东西 我相信你想要一个音量切片器。默认情况下,numpy、scipy 或 matplotlib(据我所知)都没有准备好执行此操作。您可以计算层之间的切片,但您需要构建代码来执行此操作(如果您可以接受,我可能会尝试提供解决方案)。更接近 matplotlib 的库是 Mayavi(我认为它目前仅在 Python 2.x 中可用)。你也可以考虑使用 pyQtGraph、VTK 或 Vispy。 @armatita 感谢您的回答。至少现在我确定我问的不是小事!如果你想构建一个可以做卷切片的代码,我一定会感兴趣的!谢谢。 【参考方案1】:

使用 Plotly,您可以在体积数据中绘制平面和非线性切片: http://nbviewer.jupyter.org/github/empet/Plotly-plots/blob/master/Plotly-Slice-in-volumetric-data.ipynb

【讨论】:

谢谢!会检查的。【参考方案2】:

要“识别并绘制 a=0 的二维曲面”,您只需将 a=0 处的数据子集并绘制(如下所示)如果您正在寻找数据在该平面上的投影,那么有点复杂。

threeD = np.array([(x,y,z) for x in [0,1] for y in [1,2] for z in [5,6]])
twoD = np.array([(y,z) for (x,y,z) in threeD if x==0])
y,z = zip(*twoD)
plt.plot(y,z, 'o')
plt.xlim(0,3)
plt.ylim(0,7)

【讨论】:

我认为我的问题不够清楚。正在编辑。【参考方案3】:

卷切片操作通常依赖于插值的概念,最典型的有:Nearest neighbor、Linear 和Cubic。请注意,这些方法适用于更多维数(例如参见 Bilinear 或 Trilinear 插值)。

在这种情况下,您是说您有一个卷,您可以从中检索 X、Y、Z 中的切片(或混合但不考虑这种情况,因为它是一个新的整体问题,只会带来混乱)。

因此,以切片 X=5 和 X=6 为例,您想知道如何获得 X=5.5。看看这个例子:

def linear_interpolation(p1, p2, x0):
    """
    Function that receives as arguments the coordinates of two points (x,y)
    and returns the linear interpolation of a y0 in a given x0 position. This is the
    equivalent to obtaining y0 = y1 + (y2 - y1)*((x0-x1)/(x2-x1)).
    Look into https://en.wikipedia.org/wiki/Linear_interpolation for more
    information.

    Parameters
    ----------
    p1     : tuple (floats)
        Tuple (x,y) of a first point in a line.
    p2     : tuple (floats)
        Tuple (x,y) of a second point in a line.
    x0     : float
        X coordinate on which you want to interpolate a y0.

    Return float (interpolated y0 value)
    """
    return p1[1] + (p2[1] - p1[1]) * ((x0 - p1[0]) / (p2[0] - p1[0]))

X, Y, Z = np.meshgrid(range(10), range(10), range(10))
vol = np.sqrt((X-5)**2 + (Y-5)**2 + (Z-5)**2)

Slice5dot5 = linear_interpolation((Y[5, :, :], vol[5, :, :]), (Y[6, :, :], vol[6, :, :]), 5.5)

f, (ax1, ax2, ax3) = plt.subplots(1, 3, sharey=True)
ax1.imshow(vol[5, :, :], interpolation='nearest', origin='lower', vmin=vol.min(), vmax=vol.max())
ax1.set_title("vol[5, :, :]")
ax2.imshow(Slice5dot5, interpolation='nearest', origin='lower', vmin=vol.min(), vmax=vol.max())
ax2.set_title("vol[5.5, :, :]")
ax3.imshow(vol[6, :, :], interpolation='nearest', origin='lower', vmin=vol.min(), vmax=vol.max())
ax3.set_title("vol[6, :, :]")
plt.show()

该函数似乎已记录在案(它是我做的一个旧项目的一部分),可以与数字一起使用,但它也可以与 numpy 2D 切片一起使用(并且比循环所有这些单元格要快得多)。

结果是这样的:

您会注意到颜色从左到右越来越淡。中间的切片是完全插值的,以前不存在。

【讨论】:

以上是关于matplotlib 3D 数据的 2D 切片的主要内容,如果未能解决你的问题,请参考以下文章

在 Jupyter Notebook 中使用 Matplotlib 对 3D 矩阵进行动画处理

NumPy:在 3D 切片中使用来自 argmin 的 2D 索引数组

如何在 Qt 中创建 3D 对象模型的 2D 切片?

基于 2D 数组的 3D numpy 切片的平均值

python 使用matplotlib进行2D和3D地标可视化

在numpy中获取3D数组的2D切片的平均值