Cambie el color de la barra en un gráfico de barra 3D en matplotlib según el valor

Tengo un gráfico de barras 3D en matplotlib que consta de un total de 165 barras y en este momento es bastante caótico.

introduzca la descripción de la imagen aquí .

Me gustaría cambiar el color de las barras según los valores z discretos: 0,1,2.

Sé que existe la opción de cambiar la barra de color en diagtwigs de barra 1D en función de valores específicos mediante el uso de máscaras como en el gráfico de barra de color matplotlib en función del valor .

Y también hay una pregunta sobre cómo cambiar el color de la barra en función de los valores: Definición de colores del diagtwig de barras 3D de Matplotlib

No estoy seguro de si comprendo perfectamente la respuesta dada, pero no puedo hacer que funcione en este caso.

El código es:

data = [[0 0 0 2 0 0 1 2 0 0 0] [0 0 2 2 0 0 0 0 2 0 0] [1 0 2 2 1 2 0 0 2 0 2] [1 0 2 2 0 2 0 2 2 2 2] [2 2 2 2 2 2 2 2 2 2 2] [2 2 0 2 2 2 2 2 2 2 2] [0 2 2 0 2 2 2 2 2 2 2] [1 2 0 0 2 1 2 2 0 0 2] [0 0 2 1 0 0 2 0 0 0 0] [2 1 2 2 0 0 0 2 0 0 2] [2 2 2 0 2 0 0 0 2 2 2] [2 2 0 0 2 2 2 2 2 0 0] [2 2 1 2 0 0 0 2 2 2 0] [2 0 0 2 0 0 2 2 2 2 2] [2 0 0 2 0 2 2 2 2 2 2]] ly = len(data[0]) lx = len(data[:,0]) xpos = np.arange(0,lx,1) # Set up a mesh of positions ypos = np.arange(0,ly,1) xpos, ypos = np.meshgrid(xpos+0.25, ypos+0.25) xpos = xpos.flatten() # Convert positions to 1D array ypos = ypos.flatten() zpos = np.zeros(lx*ly) dx = 0.5 * np.ones_like(zpos) dy = dx.copy() dz = data.flatten() ys = np.array([float(yi) for yi in y[1:]]) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') # all blue bars #ax.bar3d(xpos,ypos,zpos, dx, dy, dz, color='b') # try changing color bars colors = ['r','g','b'] for i in range(0,3): ax.bar3d(xpos[i], ypos[i], zpos[i], dx, dy, dz[i], alpha=0.1, color=colors[i]) ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') plt.show() 

Como se ve en la documentación de bar3d , el color puede ser una matriz, con un color por barra.

Esto hace que sea muy fácil colorear todas las barras en una sola llamada a bar3d ; solo tenemos que convertir la matriz de data a una matriz de colores que se puede hacer usando un mapa de colores,

 colors = plt.cm.jet(data.flatten()/float(data.max())) 

(Tenga en cuenta que un mapa de colores toma valores entre 0 y 1, por lo que necesitamos normalizar los valores en este rango).

Ejemplo completo:

 import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np data = np.array([ [0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 0], [0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0], [1, 0, 2, 2, 1, 2, 0, 0, 2, 0, 2], [1, 0, 2, 2, 0, 2, 0, 2, 2, 2, 2], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2], [0, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2], [1, 2, 0, 0, 2, 1, 2, 2, 0, 0, 2], [0, 0, 2, 1, 0, 0, 2, 0, 0, 0, 0], [2, 1, 2, 2, 0, 0, 0, 2, 0, 0, 2], [2, 2, 2, 0, 2, 0, 0, 0, 2, 2, 2], [2, 2, 0, 0, 2, 2, 2, 2, 2, 0, 0], [2, 2, 1, 2, 0, 0, 0, 2, 2, 2, 0], [2, 0, 0, 2, 0, 0, 2, 2, 2, 2, 2], [2, 0, 0, 2, 0, 2, 2, 2, 2, 2, 2]]) ypos, xpos = np.indices(data.shape) xpos = xpos.flatten() ypos = ypos.flatten() zpos = np.zeros(xpos.shape) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') colors = plt.cm.jet(data.flatten()/float(data.max())) ax.bar3d(xpos,ypos,zpos, .5,.5,data.flatten(), color=colors) ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') plt.show() 

introduzca la descripción de la imagen aquí