【问题标题】:3D Contour plot from data using Mayavi / Python使用 Mayavi / Python 从数据中绘制 3D 等高线图
【发布时间】:2012-03-14 05:40:08
【问题描述】:

我想使用 Mayavi 绘制 3D 等高线图,方法与本页第三个图(氢电子云模型)完全相同:

http://www.sethanil.com/python-for-reseach/5

我有一组使用我自己的模型创建的数据点,我想使用这些数据点。数据点存储在一个多维 numpy 数组中,如下所示:

XYZV = [[1, 2, 3, 4],
        [6, 7, 8, 9],
        ...
        [4, 5, 6, 7]]

数据点没有均匀分布在 XYZ 空间中,也没有按任何特定顺序存储。我认为该示例使用网格网格来生成数据点 - 我已经查过了,但完全不明白。任何帮助将不胜感激?


(来源:sethanil.com

【问题讨论】:

  • 告诉我们,到目前为止你尝试了什么。我们将从那里开始提供帮助。
  • 仅供参考,此类问题非常适合Computational Science

标签: python numpy plot contour mayavi


【解决方案1】:

您可以使用 delaunay3d 过滤器从点创建单元格。然后可以为 delaunay3d 的输出 UnstructuredGrid 创建一个 iso_surface()。如果你想要 ImageData,你可以使用 image_data_probe 过滤器。

import numpy as np
from tvtk.api import tvtk
from mayavi import mlab

points = np.random.normal(0, 1, (1000, 3))
ug = tvtk.UnstructuredGrid(points=points)
ug.point_data.scalars = np.sqrt(np.sum(points**2, axis=1))
ug.point_data.scalars.name = "value"
ds = mlab.pipeline.add_dataset(ug)
delaunay = mlab.pipeline.delaunay3d(ds)
iso = mlab.pipeline.iso_surface(delaunay)
iso.actor.property.opacity = 0.1
iso.contour.number_of_contours = 10
mlab.show()

【讨论】:

  • 嗨,当我对自己的数据使用此方法时,我不断在新窗口中弹出大量错误,最后一句是:“警告:在 C:\pisi\tmp\VTK-5.6. 0-2\work\VTK\Graphics\vtkDelaunay3D.cxx,第 488 行 vtkDelaunay3D (03AD2250):遇到 27 个退化三角形,网格质量可疑”。你知道发生了什么吗?
【解决方案2】:

诀窍是在绘制之前在网格上进行插值 - 我会为此使用 scipyR 下方是一个 (500,3) XYZ 值数组,V 是每个 XYZ 点的“幅度”。

from scipy.interpolate import griddata
import numpy as np

# Create some test data, 3D gaussian, 200 points
dx, pts = 2, 100j

N = 500
R = np.random.random((N,3))*2*dx - dx
V = np.exp(-( (R**2).sum(axis=1)) )

# Create the grid to interpolate on
X,Y,Z = np.mgrid[-dx:dx:pts, -dx:dx:pts, -dx:dx:pts]

# Interpolate the data
F = griddata(R, V, (X,Y,Z))

从这里可以快速显示我们的数据:

from mayavi.mlab import *
contour3d(F,contours=8,opacity=.2 )

这给出了一个很好的(块状)高斯。

查看griddata 的文档,注意您可以更改插值方法。如果您有更多点(在插值网格上和数据集上),则插值会越来越好地代表您要说明的基础功能。这是上面 10K 点和更精细网格的示例:

【讨论】:

  • 非常感谢。它就像一个魅力!只有一个问题:如果我想将拟合网格上的点数加倍,我会在 'dx, pts = 2, 100j' 行中更改什么?
  • @Josh 您可以将其更改为dx, pts = 2, 200j,但这会使每个维度中的点数增加一倍,因此您将获得 2^3=8 倍的点数插值。 dx 控制绘图网格的范围。对于每个线性尺寸,只需 mgrid 进行更精细的控制。
  • 我发现 griddata 函数可能需要很长时间来计算。你知道加快这个过程的任何技巧吗?
  • @Josh 您可以尝试将插值更改为最接近的而不是线性的,我还没有尝试过时序测试,所以我不确定这会有多大的不同。此外,您可以将绘图分成多个部分 - 高密度区域可以有更多的点/体素,而低密度区域可以更加稀少。不过,您必须有单独的 griddata 命令。
猜你喜欢
  • 2021-05-19
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-22
  • 2018-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多