Cómo personalizar ejes en 3D hist python / matplotlib

Estoy tratando de trazar este conjunto de datos utilizando la barra 3D

BA freq 1 2003 2 1 2003 2 2 2008 1 2 2007 2 2 2007 2 3 2004 1 1 2004 3 1 2004 3 1 2004 3 

He escrito el código aquí.

  data = pandas.DataFrame({'A':[2003,2003,2008,2007,2007,2004,2004,2004,2004] , 'B': [1,1,2,2,2,3,1,1,1] ,'C': [2,2,1,2,2,1,3,3,3] }) fig = plt.figure() ax = plt.axes(projection='3d') # put 0s on the y-axis, and put the y axis on the z-axis #ax.plot(data.A.values, data.B.values,data.freq.values, marker='o', linestyle='--', color="blue", label='ys=0, zdir=z') xpos= range(len( data.A.values)) ypos= range(len( data.B.values)) zpos= range(len( data.freq.values)) ax.bar3d(xpos, ypos, zpos, data.A.values, data.B.values,data.freq.values, color='b', alpha=0.5) x_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False) ax.xaxis.set_major_formatter(x_formatter) ax.set_xticks(data.A.values) ax.set_yticks(data.B.values) ax.set_zticks(data.freq.values) plt.savefig("test.png", dpi=300) plt.show() 

¿Pero no parece ser la forma correcta de hacerlo? ¿Alguien puede ayudar mostrando cómo personalizamos los ejes?

Funciona cuando uso la ttwig.

 ax.plot(data.A.values, data.B.values,data.freq.values,marker='o', linestyle='--', color='r') 

en lugar de bar3D

 ax.bar3d(xpos, ypos, zpos, data.A.values, data.B.values,data.freq.values, color='b', alpha=0.5) 

Pero quiero usar el histogtwig 3D para subestimar mejor.

Parece que estás malinterpretando los parámetros en la función bar3d :

bar3d(x, y, z, dx, dy, dz)

  • Los parámetros x , y y z son las coordenadas de las barras en los ejes x, y y z, respectivamente.
  • Los parámetros dx , dy y dz son los tamaños de las barras en los ejes x, y y z, respectivamente.

Por ejemplo, si desea trazar el siguiente conjunto de datos:

{'A': [1, 2], 'B': [2003, 2008] ,'freq': [2, 3] }

Tienes que definir estos parámetros así:

 import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D xpos = [1, 2] ypos = [2003, 2008] zpos = [0, 0] dx = 1 dy = 1 dz = [2, 3] fig = plt.figure() ax = plt.axes(projection='3d') ax.bar3d(xpos, ypos, zpos, dx, dy, dz) plt.show() 

Esto es:

  • Traza una barra en (1, 2003, 0) (x, y, z) con la altura 2 .
  • Traza una barra en (2, 2008, 0) (x, y, z) con la altura 3 .
  • Ambas barras tienen un tamaño de 1 en los ejes x e y, aunque podría ser menos, es solo un problema estético.

El script anterior genera la siguiente ttwig:

introduzca la descripción de la imagen aquí

Si miras la imagen, notarás algunos problemas menores de formato:

  • Los años están representados en notación exponencial.
  • Las barras no están centradas en sus coordenadas (x, y).

Realmente podemos resolver esto con algunos ajustes:

 import matplotlib import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D xpos = [1, 2] ypos = [2003, 2008] zpos = [0, 0] dx = 1 dy = 1 dz = [2, 3] # Move each (x, y) coordinate to center it on the tick xpos = map(lambda x: x - 0.5, xpos) ypos = map(lambda y: y - 0.5, ypos) fig = plt.figure() ax = plt.axes(projection='3d') ax.bar3d(xpos, ypos, zpos, dx, dy, dz) # Do not print years in exponential notation y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False) ax.yaxis.set_major_formatter(y_formatter) plt.show() 

Y finalmente esto es lo que obtendremos:

introduzca la descripción de la imagen aquí

Hay demasiados lugares en los que te equivocaste, así que solo publico lo que debería ser:

 import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D data = pd.DataFrame({'A': [1,1,2,2,2,3,1,1,1], 'B': [2003,2003,2008,2007,2007,2004,2004,2004,2004] ,'freq': [2,2,1,2,2,1,3,3,3] }) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') # put 0s on the y-axis, and put the y axis on the z-axis #ax.plot(data.A.values, data.B.values,data.freq.values, marker='o', linestyle='--', color="blue", label='ys=0, zdir=z') PV = pd.pivot_table(data, values='freq',rows='A',cols='B') xpos=np.arange(PV.shape[0]) ypos=np.arange(PV.shape[1]) xpos, ypos = np.meshgrid(xpos+0.25, ypos+0.25) xpos = xpos.flatten() ypos = ypos.flatten() zpos=np.zeros(PV.shape).flatten() dx=0.5 * np.ones_like(zpos) dy=0.5 * np.ones_like(zpos) dz=PV.values.ravel() dz[np.isnan(dz)]=0. ax.bar3d(xpos,ypos,zpos,dx,dy,dz,color='b', alpha=0.5) ax.set_xticks([.5,1.5,2.5]) ax.set_yticks([.5,1.5,2.5,3.5]) ax.w_yaxis.set_ticklabels(PV.columns) ax.w_xaxis.set_ticklabels(PV.index) ax.set_xlabel('A') ax.set_ylabel('B') ax.set_zlabel('Occurrence') plt.savefig("test.png", dpi=300) plt.show() 

introduzca la descripción de la imagen aquí