Matplotlib 3D柱状图:如何不为0值数据点添加边缘色
Matplotlib 3D柱状图0值数据点边缘色无法隐藏的解决方法
问题描述
我使用Matplotlib绘制数组的3D柱状图,需要为柱状图添加边缘色,但发现0.0值的数据点也被添上了黑色边缘色。尝试通过循环为0值点设置edgecolors='none'但无效,寻求解决方法。
原绘图脚本
from mpl_toolkits.mplot3d import Axes3D fig = plt.figure() ax = Axes3D(fig) lx= len(r[0]) ly= len(r[:,0]) xpos = np.arange(0,lx,1) ypos = np.arange(0,ly,1) xpos, ypos = np.meshgrid(xpos+0.25, ypos+0.25) xpos = xpos.flatten() ypos = ypos.flatten() zpos = np.zeros(lx*ly) cs = ['r', 'g', 'b', 'y', 'c'] * ly edgecolor_store = [] dx = 0.5 * np.ones_like(zpos) dy = 0 * np.ones_like(zpos) #dz = zpos dz = r.flatten() for value in dz: if value == 0.0: edgecolor_store.append('none') if value > 0.0: edgecolor_store.append('black') mask_dz = dz == 0 # SO:60111736, 3d case #print(dz) ax.bar3d(xpos,ypos,zpos, dx, dy,dz,color=cs,zsort='average',alpha=0.5,edgecolors=edgecolor_store)
示例数据
[ 0. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 20.7, 0. , 0. ], [ 0.6, 0. , 0.1, 0. , 0.2], [ 0. , 24.8, 0. , 46.7, 0. ], [ 0. , 0. , 99.7, 17.1, 99.3], [ 0. , 12.8, 98.6, 0. , 6.7], [ 0.2, 0. , 0. , 12.6, 0. ]
当前问题表现
输出图中大量0值位置仍显示黑色边缘线,干扰正常可视化效果。
解决方法
问题根源在于:当dz=0时,bar3d仍会绘制高度为0的柱体,即使设置edgecolor='none',Matplotlib的3D渲染逻辑依然会显示边缘。正确方案是直接过滤掉所有0值数据点,仅绘制有数值的柱体。
修改后的完整代码
from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt import numpy as np # 定义示例数据 r = np.array([ [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 20.7, 0., 0.], [0.6, 0., 0.1, 0., 0.2], [0., 24.8, 0., 46.7, 0.], [0., 0., 99.7, 17.1, 99.3], [0., 12.8, 98.6, 0., 6.7], [0.2, 0., 0., 12.6, 0.] ]) fig = plt.figure() ax = Axes3D(fig) lx = len(r[0]) ly = len(r[:,0]) xpos = np.arange(0, lx, 1) ypos = np.arange(0, ly, 1) xpos, ypos = np.meshgrid(xpos + 0.25, ypos + 0.25) xpos = xpos.flatten() ypos = ypos.flatten() zpos = np.zeros(lx * ly) cs = ['r', 'g', 'b', 'y', 'c'] * ly dx = 0.5 * np.ones_like(zpos) dy = 0 * np.ones_like(zpos) dz = r.flatten() # 过滤掉所有0值数据点 mask = dz != 0 xpos_filtered = xpos[mask] ypos_filtered = ypos[mask] zpos_filtered = zpos[mask] dx_filtered = dx[mask] dy_filtered = dy[mask] dz_filtered = dz[mask] # 匹配过滤后的颜色列表 cs_filtered = [cs[i] for i in range(len(cs)) if mask[i]] # 仅为非0柱体设置黑色边缘 edgecolor_store = ['black'] * len(dz_filtered) ax.bar3d(xpos_filtered, ypos_filtered, zpos_filtered, dx_filtered, dy_filtered, dz_filtered, color=cs_filtered, zsort='average', alpha=0.5, edgecolors=edgecolor_store) plt.show()
修改说明
- 添加掩码
mask = dz != 0,筛选出所有非0值的坐标、尺寸、颜色参数 - 仅对非0柱体设置黑色边缘,0值数据直接不绘制,从根源避免边缘线问题
- 补充了示例数据的numpy数组定义,修复原代码中可能的未定义变量问题
内容的提问来源于stack exchange,提问作者Dimuthu Kodituwakku
相关产品推荐
相关产品推荐

