如何在Matplotlib/Python中绘制与示例一致的3D网格块?
实现目标3D网格块的绘制方案
针对你需要的每个网格节点对应大小、颜色可变的高不透明度3D块效果,以下两种优化方案可以解决基础scatter和voxel的不足:
一、优化版Scatter3D实现
基础scatter效果差的核心原因是标记形状和大小控制不到位,调整参数后可以贴近需求:
- 使用立方体标记(
marker='s')替代默认圆点,更接近示例的块形态 - 将
s参数绑定到数值,通过缩放因子实现大小随数值变化 - 设置高透明度(
alpha=0.8~0.9),保证块的厚重感 - 用
cmap映射数值到颜色,配合c参数绑定节点数值
示例代码:
import matplotlib.pyplot as plt import numpy as np # 生成网格数据(示例) x, y, z = np.meshgrid(np.arange(5), np.arange(5), np.arange(5)) values = np.random.rand(5,5,5) * 100 # 对应每个节点的数值 # 扁平化数据适配scatter输入 x_flat = x.flatten() y_flat = y.flatten() z_flat = z.flatten() vals_flat = values.flatten() fig = plt.figure() ax = fig.add_subplot(projection='3d') # 绘制3D散点图 scatter = ax.scatter3D(x_flat, y_flat, z_flat, s=vals_flat * 5, # 缩放因子根据需求调整 c=vals_flat, cmap='viridis', marker='s', alpha=0.85) # 添加颜色条展示数值对应关系 plt.colorbar(scatter) plt.show()
二、Poly3DCollection绘制自定义立方体块(更贴近示例效果)
如果需要完全规整的立方体块,用Poly3DCollection手动生成每个块的几何体,能精准控制大小和位置:
- 定义生成单个立方体顶点的函数,输入中心坐标和边长
- 遍历每个网格节点,根据数值计算块的边长
- 从colormap中获取对应数值的颜色,生成立方体并添加到画布
示例代码:
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d.art3d import Poly3DCollection import numpy as np # 生成单个立方体的面顶点函数 def make_cube(center, side_length): x0, y0, z0 = center half = side_length / 2 # 立方体8个顶点坐标 vertices = [ [x0-half, y0-half, z0-half], [x0+half, y0-half, z0-half], [x0+half, y0+half, z0-half], [x0-half, y0+half, z0-half], [x0-half, y0-half, z0+half], [x0+half, y0-half, z0+half], [x0+half, y0+half, z0+half], [x0-half, y0+half, z0+half] ] # 定义立方体的6个面 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[2], vertices[3], vertices[7], vertices[6]], [vertices[0], vertices[3], vertices[7], vertices[4]], [vertices[1], vertices[2], vertices[6], vertices[5]] ] return faces # 生成网格数据 x, y, z = np.meshgrid(np.arange(5), np.arange(5), np.arange(5)) values = np.random.rand(5,5,5) * 0.8 + 0.2 # 控制边长范围在0.2~1.0之间 fig = plt.figure() ax = fig.add_subplot(projection='3d') # 遍历每个节点绘制立方体 cmap = plt.get_cmap('viridis') norm = plt.Normalize(values.min(), values.max()) for i in range(x.shape[0]): for j in range(x.shape[1]): for k in range(x.shape[2]): center = (x[i,j,k], y[i,j,k], z[i,j,k]) side = values[i,j,k] faces = make_cube(center, side) # 获取当前数值对应的颜色 color = cmap(norm(values[i,j,k])) # 添加立方体到画布,设置高透明度 cube = Poly3DCollection(faces, facecolors=color, alpha=0.9, edgecolors='white') ax.add_collection3d(cube) # 设置坐标轴范围适配网格 ax.set_xlim(-0.5, 4.5) ax.set_ylim(-0.5, 4.5) ax.set_zlim(-0.5, 4.5) plt.show()
这种方法生成的块是标准立方体,大小和颜色精准对应数值,透明度可调,和你需要的示例效果匹配度更高。
内容的提问来源于stack exchange,提问作者KooH
相关产品推荐
相关产品推荐

