pythonmatplotlibmplot3d

Matplotlib edgecolors coloring 0.0 valued data points


I'm plotting a 3d bar plot for an array using matplotlib. I need to add an edgecolor to the bars. However, the edgecolor is coloring the 0.0 values data points in black. Is there a way to not color these data points? I'm trying to do edgecolors=none through a loop when values are 0.0. However this doesn't seem to help. Any help appreciated.

The script I use to plot,

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)

Sample data I use,

[  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. ]

The output plot I get is,

enter image description here


Solution

  • I feel that you've already tried the correct solution: not plot the unwanted bars.

    You need a mask. Btw, never ever compare floats with ==.

    mask = ~np.isclose(dz, 0.0)
    

    Then, plot data filtered by this mask

    ax.bar3d(xpos[mask],ypos[mask],zpos[mask], dx[mask], dy[mask],dz[mask],color=cs[:mask.sum()],zsort='average',alpha=0.5,edgecolors='black')
    

    Note that you no longer need edgecolor. And that my way of computing cs (starting from your too long cs, and truncating it to the exact needed size) is not optimal.

    enter image description here

    Also note that the 4 remaining black lines are not 0, but very small (0.1, 0.2, 0.2 and 0.6) values.