I've got a piece of code that plots a dataframe in 3 dimensions, each column being added to the plot inside a loop. The code is inspired from this post (How to order dataframe for plotting 3d bar in pandas), but since it's quite old, I thought writing about it in a separate one.
df = pd.DataFrame(index = index, data = np.random.randint(0,100,size=(366, 6)), columns=list('ABCDEF'))
ind = 0
colors = ['darkred','darkgreen','dodgerblue','gold','royalblue','purple']
for i in reversed(range(0, len(df.columns),1)):
col_name = df.columns[i]
xpos= np.arange(df.shape[0])
ypos= (df.shape[1]-1) - ind
xpos, ypos = np.meshgrid(xpos+0.25, ypos+0.25)
xpos = xpos.flatten()
ypos = ypos.flatten()
zpos=np.zeros(df.shape[0]).flatten()
dx=0.5 * np.ones_like(zpos)
dy=0.1 * np.ones_like(zpos)
dz=df[str(col_name)].values.ravel()
ax.bar3d(xpos,ypos,zpos,dx,dy,dz, color=colors[i], alpha=0.1,
label=str(col_name))
ind += 1
ax.set_yticks([.5,1.5,2.5,3.5,4.5,5.5])
ax.w_yaxis.set_ticklabels(df.columns)
ax.set_xlabel('Day of Year')
ax.set_ylabel('Device')
ax.set_zlabel('Production')
plt.show()
I've got two problems here. First, an overlapping issue (see the picture below). The columns with the overall large values are plotted in the background and, as the averages decrease, they are plotted to the foreground. But, even though that I tried to 'hack' it and plot from the last column to the first one (see the code snippet), it still overwrites the purple plot over the blue one in front of it, or the yellow one over the other blue one... Any ideas how can that be fixed?
The second problem is related to the legend. The plots have labels, but if I try the basic ax.legend() command, the following error appears:
AttributeError: 'Poly3DCollection' object has no attribute '_edgecolors2d'
I have also tried to create Rectangle proxies for every plot, inside the loop and relating them to the name of the columns, but it didn't work either. Any thoughts?