如何用Python绘制基于矩阵定义高度与颜色的3D柱状图?
解决3D柱状图按自定义颜色矩阵着色的问题
嘿,我明白你想要实现的是每个3D柱体的高度由z矩阵定义,同时颜色对应colors矩阵的数值——这确实是mplot3d自带示例里没怎么覆盖到的场景,因为默认的bar3d不太支持直接按每个柱体单独映射颜色。不过别担心,我们可以手动遍历每个柱体,给它们单独设置颜色,步骤如下:
完整实现代码
from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt import numpy as np from matplotlib import cm from matplotlib.colors import Normalize # 定义你的原始数据 x_axis = ["Piccola", "Media", "Grande"] y_axis = [1,0.9,0.8,0.7,0.6,0.5,0.4,0.3,0.2,0.1] z = [ [0.03,0.18,0.24,0.12,0.9,0.21,0.06,0.24,-0.06,-0.24], [0,0.03,0.03,-0.06,0.03,0,-0.03,-0.03,-0.09,-0.09], [0,0,-0.03,-0.03,-0.06,-0.06,-0.03,-0.06,-0.09,-0.29] ] colors =[ [24.67,27.50,30.25,25.6,31.87,42.67,31.39,49.58,50.27,53.76], [17.17,21.67,21.96,22.11,19.45,17.44,17.95,22.51,28.21,46.14], [17.18,18.01,17.68,15.03,17.80,17.93,14.75,18.88,24.7,39.75] ] # 转换为numpy数组方便处理 z = np.array(z) colors = np.array(colors) x = np.arange(len(x_axis)) # 把x轴标签转为数值索引 y = np.array(y_axis) # 设置柱体的尺寸(避免重叠) dx = 0.8 # x方向柱体宽度 dy = 0.08 # y方向柱体宽度 # 归一化颜色值到0-1区间(适配colormap) norm = Normalize(vmin=colors.min(), vmax=colors.max()) cmap = cm.viridis # 你可以更换成其他colormap,比如plasma、coolwarm等 # 创建3D画布 fig = plt.figure(figsize=(12,8)) ax = fig.add_subplot(111, projection='3d') # 遍历每个柱体,单独设置高度和颜色 for i in range(len(x)): for j in range(len(y)): # 获取当前柱体的高度和颜色值 z_val = z[i,j] color_val = colors[i,j] # 把颜色值转为colormap对应的RGBA rgba = cmap(norm(color_val)) # 绘制单个柱体:bar3d(x0, y0, z0, dx, dy, dz) ax.bar3d(x[i] - dx/2, y[j] - dy/2, 0, dx, dy, z_val, color=rgba) # 设置轴标签 ax.set_xticks(x) ax.set_xticklabels(x_axis) ax.set_yticks(y) ax.set_yticklabels(y) ax.set_zlabel('Z Value') ax.set_title('3D Bar Chart with Custom Color Mapping') # 添加颜色条,展示颜色和数值的对应关系 sm = cm.ScalarMappable(norm=norm, cmap=cmap) sm.set_array([]) fig.colorbar(sm, ax=ax, pad=0.1, label='Color Value') plt.show()
关键步骤解释
- 数据转换:先把
z和colors转成numpy数组,方便索引和计算;把x轴的文本标签转为数值索引,方便定位柱体位置。 - 颜色归一化:因为matplotlib的colormap只接受0-1之间的数值,所以用
Normalize把colors矩阵里的数值缩放到这个区间,确保颜色映射的连续性。 - 逐个绘制柱体:遍历每个x和y的组合,单独调用
bar3d绘制每个柱体,并传入对应的归一化颜色值,这样每个柱体就能匹配colors矩阵里的数值了。 - 颜色条添加:通过
ScalarMappable创建颜色条,让读者能直观看到颜色和colors数值的对应关系。
你可以根据需求更换colormap(比如把cm.viridis换成cm.coolwarm),或者调整柱体的尺寸(dx和dy)来优化显示效果。
内容的提问来源于stack exchange,提问作者roy
相关产品推荐
相关产品推荐

