NumPy 标志的 3D 体素图

Beginner

This tutorial is from open-source community. Access the source code

简介

本实验展示了如何使用 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 数组,名为 facecolorsedgecolors,它们将用于为体素着色。

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 的函数来放大标志的体素图像。