代码如下:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
from matplotlib.colors import LinearSegmentedColormap, Normalize
import numpy as np
def make_cube(matrix: np.ndarray)->None:
fig = plt.figure(figsize=(28, 25), dpi=360)
ax = fig.add_subplot(111, projection='3d')
cube_size = 15
gap = 2 * cube_size
center_x = (2.5 * cube_size + (6 - 1) * gap) / 2
center_y = (2.5 * cube_size + (6 - 1) * gap) / 2
center_z = (2.5 * cube_size + (5 - 1) * gap) / 2
normalized_matrix = (matrix - matrix.min()) / (matrix.max() - matrix.min()) * 254
colors = [(1, 1, 1), (0, 0, 0)]
cmap_name = 'custom_cmap'
n_colors = 256
cmap = LinearSegmentedColormap.from_list(cmap_name, colors, N=n_colors)
norm = Normalize(vmin=0, vmax=255) # 定义数值范围
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
for i in range(5):
for j in range(6):
for k in range(6):
x = center_x - (2.5 * cube_size + (6 - 1) * gap) + 0.7* j * (cube_size + gap)
y = center_y - (2.5 * cube_size + (6 - 1) * gap) + 0.7* i * (cube_size + gap)
z = center_z - (2.5 * cube_size + (5 - 1) * gap) + k * (cube_size + 1.8*gap)
vertices = np.array([
[x, y, z],
[x + cube_size, y, z],
[x + cube_size, y + cube_size, z],
[x, y + cube_size, z],
[x, y, z + cube_size],
[x + cube_size, y, z + cube_size],
[x + cube_size, y + cube_size, z + cube_size],
[x, y + cube_size, z + cube_size]
])
faces = [
[vertices[0], vertices[1], vertices[2], vertices[3]],
[vertices[4], vertices[5], vertices[6], vertices[7]],
[vertices[0], vertices[1], vertices[5], vertices[4]],
[vertices[1], vertices[2], vertices[6], vertices[5]],
[vertices[2], vertices[3], vertices[7], vertices[6]],
[vertices[3], vertices[0], vertices[4], vertices[7]]
]
value = normalized_matrix[i, j, k]
color = cmap(norm(value))
collection = Poly3DCollection(faces, facecolors=color, linewidths=1.5, edgecolors='black')
ax.add_collection3d(collection)
ax.set_xlim(center_x - (2.5 * cube_size + (6 - 1) * gap) - 0.5, center_x + (2.5 * cube_size + (6 - 1) * gap) - 100)
ax.set_ylim(center_y - (2.5 * cube_size + (6 - 1) * gap) - 0.5, center_y + (2.5 * cube_size + (6 - 1) * gap) - 100)
ax.set_zlim(center_z - (2.5 * cube_size + (5 - 1) * gap) - 0.5, center_z + (2.5 * cube_size + (5 - 1) * gap) - 60)
ax.view_init(elev=15, azim=-50)
ax.axis('off')
fig.patch.set_facecolor('none')
cbar = fig.colorbar(sm, shrink=0.4)
cbar.set_ticks([0, 255])
cbar.set_ticklabels(['{:.0f}'.format(matrix.min()), '{:.0f}'.format(matrix.max())])
效果如图:
# Example usage:
matrix = np.random.randint(0, 512, size=(5, 6, 6)) # 生成一个5x6x6的随机矩阵
make_cube(matrix)