You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:使用Matplotlib绘制带单元格的3D网格数据热力图

问题描述

我尝试将数据可视化为立方体,希望能绘制出立方体内部的每个单元格。目前生成的是未分割单元格的立方体,但需要实现类似3D热力图的效果,将预测结果可视化为带热力图的3D立方体。以下是我编写的代码:

%matplotlib notebook
%matplotlib inline
from mpl_toolkits.mplot3d import Axes3D
matplotlib.rcParams['backend'] = "Qt4Agg"
import numpy as np

#each sell has its value

y_pred = ([-3.4942558e+01, -1.0922590e+01, -9.4551229e+00, -2.6156654e+01,
        1.1722648e+01,  6.4425749e-01, -1.1141028e+01,  5.9728470e+01,
       -4.5249408e-01, -8.7741699e+00,  9.9452820e+00, -2.8595707e+00,
        2.6979692e+00,  7.9802217e+00, -1.1204488e+00, -4.5213123e+01,
       -7.1909481e-01, -8.4901733e+00, -9.2283611e+00,  5.0730385e+01,
       -7.9520082e-01,  1.4589276e+02,  8.4267479e+01, -6.7399621e+00,
        2.1536992e+02,  5.0958019e+01, -7.7071385e+00,  8.4650040e+01,
        2.5421507e+01, -4.1403370e+00, -8.5559702e+00,  5.5478176e+01,
       -1.0955868e+01,  3.1425345e+02,  1.9285686e+02,  4.6105843e+00,
        6.6680554e+02,  2.7745572e+02,  1.2241451e+01,  5.1578967e+02,
        1.8129390e+02,  7.3322144e+00,  1.2733205e+02,  4.4435711e+01,
       -2.0441423e-01,  8.3673248e+01,  1.7386259e+02, -1.6146477e-01,
        5.9598431e+02,  5.7501422e+02,  4.7413929e+01,  7.6495886e+02,
        6.5124884e+02,  7.9399048e+01,  4.0769174e+02,  3.2358469e+02,
        3.6726327e+00,  7.5896362e+01,  9.8999245e+01, -1.7699455e+00,
        1.0632815e+02,  2.3123619e+02,  4.5826878e+01,  3.6063211e+02,
        5.6004309e+02,  1.3757048e+02,  3.7029037e+02,  5.5426331e+02,
        1.0625824e+02,  1.7360068e+02,  2.6583237e+02,  2.0798336e+01,
        4.7036118e+01,  7.3350151e+01,  9.1420832e+00])

ex1 = np.trunc(y_pred).reshape(5,5,3)

max_value = np.amax(ex1)
min_value = np.amin(ex1)
average = 1/2*(min_value + max_value)
mean_value = np.mean(ex1)
print(f"max: {max_value}\nmin: {min_value}\naverage: {average}\nmean: {mean_value}")

x = 5
y = 5
z = 3

axes = [5, 5, 3]
data = np.ones(axes, dtype=bool)

alpha = 0.5

colors = np.empty(axes + [4])

for x1 in range(x):
    for y1 in range(y):
        for z1 in range(z):
            if ex1[x1][y1][z1] >= average: 
                colors[x1][y1][z1] = [1, 0, 0, alpha] 
                
            elif ex1[x1][y1][z1] > mean_value:
                colors[x1][y1][z1] = [1, 1, 0, alpha] 
            
            elif ex1[x1][y1][z1] <= mean_value:
                colors[x1][y1][z1] = [0, 0, 1, alpha]        
    
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.voxels(data, facecolors=colors, edgecolors='grey')
ax.axis('on')
ax.set_aspect('auto')

plt.show()
解决方案

要实现带渐变热力效果的3D单元格立方体,核心是用**颜色映射(colormap)**替代固定三色划分,让每个单元格颜色随数值连续渐变,同时强化单元格分割显示。以下是修改后的代码:

%matplotlib notebook
%matplotlib inline
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from matplotlib.colors import Normalize
import numpy as np

# 预测数据
y_pred = ([-3.4942558e+01, -1.0922590e+01, -9.4551229e+00, -2.6156654e+01,
        1.1722648e+01,  6.4425749e-01, -1.1141028e+01,  5.9728470e+01,
       -4.5249408e-01, -8.7741699e+00,  9.9452820e+00, -2.8595707e+00,
        2.6979692e+00,  7.9802217e+00, -1.1204488e+00, -4.5213123e+01,
       -7.1909481e-01, -8.4901733e+00, -9.2283611e+00,  5.0730385e+01,
       -7.9520082e-01,  1.4589276e+02,  8.4267479e+01, -6.7399621e+00,
        2.1536992e+02,  5.0958019e+01, -7.7071385e+00,  8.4650040e+01,
        2.5421507e+01, -4.1403370e+00, -8.5559702e+00,  5.5478176e+01,
       -1.0955868e+01,  3.1425345e+02,  1.9285686e+02,  4.6105843e+00,
        6.6680554e+02,  2.7745572e+02,  1.2241451e+01,  5.1578967e+02,
        1.8129390e+02,  7.3322144e+00,  1.2733205e+02,  4.4435711e+01,
       -2.0441423e-01,  8.3673248e+01,  1.7386259e+02, -1.6146477e-01,
        5.9598431e+02,  5.7501422e+02,  4.7413929e+01,  7.6495886e+02,
        6.5124884e+02,  7.9399048e+01,  4.0769174e+02,  3.2358469e+02,
        3.6726327e+00,  7.5896362e+01,  9.8999245e+01, -1.7699455e+00,
        1.0632815e+02,  2.3123619e+02,  4.5826878e+01,  3.6063211e+02,
        5.6004309e+02,  1.3757048e+02,  3.7029037e+02,  5.5426331e+02,
        1.0625824e+02,  1.7360068e+02,  2.6583237e+02,  2.0798336e+01,
        4.7036118e+01,  7.3350151e+01,  9.1420832e+00])

# 重塑为5x5x3的三维数组,保留原始浮点值(避免截断丢失精度)
ex1 = np.array(y_pred).reshape(5,5,3)

max_value = np.amax(ex1)
min_value = np.amin(ex1)
print(f"max: {max_value}\nmin: {min_value}")

# 设置坐标轴维度
axes = [5, 5, 3]
data = np.ones(axes, dtype=bool)

alpha = 0.7  # 调整透明度,让内部单元格可见

# 创建归一化器和颜色映射
norm = Normalize(vmin=min_value, vmax=max_value)
cmap = cm.viridis  # 可替换为plasma、inferno等其他颜色映射

# 生成每个单元格的颜色
colors = np.empty(axes + [4])
for x1 in range(axes[0]):
    for y1 in range(axes[1]):
        for z1 in range(axes[2]):
            # 归一化数值后映射为对应RGBA颜色
            rgba = cmap(norm(ex1[x1][y1][z1]))
            rgba[3] = alpha  # 设置透明度
            colors[x1][y1][z1] = rgba

# 绘制3D立方体
fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111, projection='3d')

# 绘制单元格,设置边缘颜色增强分割感
ax.voxels(data, facecolors=colors, edgecolors='lightgrey', linewidth=0.5)

# 设置坐标轴标签
ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
ax.set_zlabel('Z轴')

# 添加颜色条,对应数值与颜色关系
sm = cm.ScalarMappable(norm=norm, cmap=cmap)
sm.set_array([])
fig.colorbar(sm, ax=ax, shrink=0.6, pad=0.1)

ax.axis('on')
ax.set_aspect('auto')

plt.show()

关键改动说明

  • 保留原始数值精度:移除np.trunc(),避免截断导致的颜色渐变失真
  • 连续颜色映射:用Normalize将数值归一化后,通过matplotlib内置颜色映射生成渐变色彩,更贴合热力图需求
  • 强化单元格分割:设置edgecolors='lightgrey'和linewidth=0.5,让每个单元格边界清晰可辨
  • 添加颜色条:直观展示数值与颜色的对应关系,提升可视化可读性
  • 调整透明度:alpha=0.7确保内部单元格也能被观察到

内容的提问来源于stack exchange,提问作者Said Tojiboev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 06:45:36