从NumPy数组绘制3D图像

11

我有一个NumPy数组的数据文件,我想查看3D图像。我分享了一个示例,在这个示例中,我可以查看大小为(100,100)的2D图像,这是在z = 0处的xy平面切片。

import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
X, Y, Z = np.mgrid[-10:10:100j, -10:10:100j, -10:10:100j]
T = np.sin(X*Y*Z)/(X*Y*Z)
T=T[:,:,0]
im = plt.imshow(T, cmap='hot')
plt.colorbar(im, orientation='vertical')
plt.show()

在 z=0 时的切片图像

如何查看一个形状为 (100, 100, 100) 的数据T的三维图像?


1
你的问题似乎与这个类似:https://dev59.com/4lrUa4cB1Zd3GeqPgx58 - Giorgio
2
@George 我觉得这个问题质量要高得多,可能会从比链接问题上给出的更实质性的答案中受益。 - Mast
是的,既然Nachi提供了数据,那么展示这些数据的各种可视化方法的截图会很不错,而链接的问题中并没有这些。 - Eric
2个回答

2

我已经找到了解决问题的方法。如果我们有NumPy数据,那么我们可以将它们转换为TVTK ImageData,然后使用Mayavi的mlab帮助进行可视化。以下是代码及其3D可视化结果:


from tvtk.api import tvtk
import numpy as np
from mayavi import mlab
X, Y, Z = np.mgrid[-10:10:100j, -10:10:100j, -10:10:100j]
data = np.sin(X*Y*Z)/(X*Y*Z)
i = tvtk.ImageData(spacing=(1, 1, 1), origin=(0, 0, 0))
i.point_data.scalars = data.ravel()
i.point_data.scalars.name = 'scalars'
i.dimensions = data.shape
mlab.pipeline.surface(i)
mlab.colorbar(orientation='vertical')
mlab.show()

这里输入图片描述

对于另一个随机生成的数据

from numpy import random
data = random.random((20, 20, 20))

可视化将如下所示:

enter image description here


2
我认为主要问题在于每个点都有4个信息,因此你实际上对一个四维物体感兴趣。绘制这个图形总是很困难(甚至可能是不可能的)。我建议采用以下解决方案之一:
  1. 您将问题改为:我只对中的z = f(x,y)感兴趣,而不是所有组合。

  2. 您略微调整绘图精度,表示您不需要100个z级别,而只需要5个,然后您可以简单地制作5个已有的图形。

如果您想使用第一种方法,则有几种子方法:

A. 绘制二维曲面f(x,y)=z并使用T进行着色 B. 使用任何用于绘制复杂函数的技术,有关更多信息,请参见此处

使用方法1.A(我认为是最佳解决方案)绘制出z=x^2+y^2的图形如下: enter image description here 我使用了这个程序:
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib as mpl
X, Y = np.mgrid[-10:10:100j, -10:10:100j]
Z = (X**2+Y**2)/10 #definition of f
T = np.sin(X*Y*Z)
norm = mpl.colors.Normalize(vmin=np.amin(T), vmax=np.amax(T))
T = mpl.cm.hot(T) #change T to colors
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(X, Y, Z, facecolors=T, linewidth=0,
       cstride = 1, rstride = 1)
plt.show()

第二种方法会得到类似于以下内容:

输入图像描述这里

代码如下:
norm = mpl.colors.Normalize(vmin=-1, vmax=1)
X, Y= np.mgrid[-10:10:101j, -10:10:101j]
fig = plt.figure()
ax = fig.gca(projection='3d')
for i in np.linspace(-1,1,5):
    Z = np.zeros(X.shape)+i
    T = np.sin(X*Y*Z)
    T = mpl.cm.hot(T)
    ax.plot_surface(X, Y, Z, facecolors=T, linewidth=0, alpha = 0.5, cstride 
        = 10, rstride = 10)

plt.show()

注意:我将函数更改为T = sin(X * Y * Z),因为除以X * Y * Z会使函数的行为变得糟糕,因为您将两个非常接近于0的数字相除。

感谢您的建议。问题不是要在第四维中绘制表面,而是将数据可视化为三维图形。每个点处的数据应该用一种颜色来表示。这也不应该是等高线图,因为等高线代表了等值线的集合。 - Nachi
在matplotlib版本3.7.3中,使用"ax = fig.add_subplot(projection='3d')"代替"ax = fig.gca(projection='3d')"。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接