简介
本实验展示了如何使用 Matplotlib 中的 Axes3D.voxels 函数创建 NumPy 标志的 3D 体素图。
虚拟机使用提示
虚拟机启动完成后,点击左上角切换到 笔记本 标签页,以访问 Jupyter Notebook 进行练习。
有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。
如果你在学习过程中遇到问题,随时向 Labby 提问。课程结束后提供反馈,我们会及时为你解决问题。
导入库
首先,我们需要导入必要的库,即 Matplotlib 和 NumPy。
import matplotlib.pyplot as plt
import numpy as np
定义展开函数
接下来,我们定义一个名为 explode 的函数,该函数将用于放大 NumPy 标志的体素图像。此函数接受一个 NumPy 数组作为输入,并返回一个新的 NumPy 数组,其大小是输入数组的两倍。
def explode(data):
size = np.array(data.shape)*2
data_e = np.zeros(size - 1, dtype=data.dtype)
data_e[::2, ::2, ::2] = data
return data_e
构建 NumPy 标志
现在我们可以开始使用一个名为 n_voxels 的 3D NumPy 数组来构建 NumPy 标志了。我们将数组中的某些元素设置为 True 以表示标志的形状。我们还定义了另外两个 NumPy 数组,名为 facecolors 和 edgecolors,它们将用于为体素着色。
n_voxels = np.zeros((4, 3, 4), dtype=bool)
n_voxels[0, 0, :] = True
n_voxels[-1, 0, :] = True
n_voxels[1, 0, 2] = True
n_voxels[2, 0, 1] = True
facecolors = np.where(n_voxels, '#FFD65DC0', '#7A88CCC0')
edgecolors = np.where(n_voxels, '#BFAB6E', '#7D84A6')
放大体素图像
我们现在使用之前定义的 explode 函数来放大体素图像,使每个体素之间留出间隙。
filled = np.ones(n_voxels.shape)
filled_2 = explode(filled)
fcolors_2 = explode(facecolors)
ecolors_2 = explode(edgecolors)
缩小间隙
我们使用 NumPy 的 indices 函数修改每个体素的坐标,从而缩小每个体素之间的间隙。
x, y, z = np.indices(np.array(filled_2.shape) + 1).astype(float) // 2
x[0::2, :, :] += 0.05
y[:, 0::2, :] += 0.05
z[:, :, 0::2] += 0.05
x[1::2, :, :] += 0.95
y[:, 1::2, :] += 0.95
z[:, :, 1::2] += 0.95
创建体素图
最后,我们使用 Matplotlib 中 Axes3D 类的 voxels 函数创建 3D 体素图。
ax = plt.figure().add_subplot(projection='3d')
ax.voxels(x, y, z, filled_2, facecolors=fcolors_2, edgecolors=ecolors_2)
ax.set_aspect('equal')
plt.show()
总结
本实验展示了如何使用 Matplotlib 创建 NumPy 标志的 3D 体素图。我们使用 NumPy 构建标志,并使用 Axes3D.voxels 函数创建图形。我们还使用了一个名为 explode 的函数来放大标志的体素图像。