使用 Mayavi / Python 根据数据绘制 3D 轮廓图

发布于 2025-01-08 03:50:53 字数 731 浏览 0 评论 0原文

我想使用 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 空间中,也不以任何特定顺序存储。我认为该示例使用网格来生成数据点 - 我已经查过这一点,但完全不理解它。任何帮助将不胜感激?

H
(来源:sethanil。 com)

I would like to do a 3D contour plot using Mayavi in exactly the same way as the third figure on this page (a hydrogen electron cloud model) :

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

I have a set of data points which I created using my own model which I would like to use. The data points are stored in a multi-dimensional numpy array like so:

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

The data points are not uniformly spread in XYZ space and not stored in any particular order. I think the example uses a meshgrid to generate the data points - I have looked this up but totally don't understand it. Any help would be much appreciated?

H
(source: sethanil.com)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风月客 2025-01-15 03:50:53

诀窍是在绘图之前在网格上进行插值 - 我会使用 scipy 来实现此目的。下面的 R 是 XYZ 值的 (500,3) 数组,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 点和更精细网格的示例:

在此处输入图像描述

The trick is to interpolate over a grid before you plot - I'd use scipy for this. Below R is a (500,3) array of XYZ values and V is the "magnitude" at each XYZ point.

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 here it's a snap to display our data:

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

This gives a nice (lumpy) Gaussian.

enter image description here

Take a look at the docs for griddata, note that you can change the interpolation method. If you have more points (both on the interpolated grid, and on the data set), the interpolation gets better and better represents the underlying function you're trying to illustrate. Here is the above example at 10K points and a finer grid:

enter image description here

青朷 2025-01-15 03:50:53

您可以使用 delaunay3d 过滤器从点创建单元格。然后您可以为 delaunay3d 的输出 UnstructedGrid 创建一个 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()

在此处输入图像描述

You can use delaunay3d filter to create cells from points. Then you can create an iso_surface() for the output UnstructuredGrid of delaunay3d. If you want ImageData, you can use image_data_probe filter.

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

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文