OK I have some code that I'm using to plot 3d charts in matplotlib (based on this great answer here). Here's the simplified version:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
plt.close("all")
data1 = pd.DataFrame.from_dict(
{
"0": {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10},
"1": {0: 10, 1: 0, 2: 1, 3: 2, 4: 3, 5: 4, 6: 5, 7: 6, 8: 7, 9: 8, 10: 9},
"2": {0: 9, 1: 10, 2: 0, 3: 1, 4: 2, 5: 3, 6: 4, 7: 5, 8: 6, 9: 7, 10: 8},
"3": {0: 8, 1: 9, 2: 10, 3: 0, 4: 1, 5: 2, 6: 3, 7: 4, 8: 5, 9: 6, 10: 7},
"4": {0: 7, 1: 8, 2: 9, 3: 10, 4: 0, 5: 1, 6: 2, 7: 3, 8: 4, 9: 5, 10: 6},
"5": {0: 6, 1: 7, 2: 8, 3: 9, 4: 10, 5: 0, 6: 1, 7: 2, 8: 3, 9: 4, 10: 5},
"6": {0: 5, 1: 6, 2: 7, 3: 8, 4: 9, 5: 10, 6: 0, 7: 1, 8: 2, 9: 3, 10: 4},
"7": {0: 4, 1: 5, 2: 6, 3: 7, 4: 8, 5: 9, 6: 10, 7: 0, 8: 1, 9: 2, 10: 3},
"8": {0: 3, 1: 4, 2: 5, 3: 6, 4: 7, 5: 8, 6: 9, 7: 10, 8: 0, 9: 1, 10: 2},
"9": {0: 2, 1: 3, 2: 4, 3: 5, 4: 6, 5: 7, 6: 8, 7: 9, 8: 10, 9: 0, 10: 1},
"10": {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10, 10: 0},
}
)
data2 = pd.DataFrame.from_dict(
{
"0": {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10},
"1": {0:np.nan,1:0.0,2:1.0,3:2.0,4:3.0,5:4.0,6:5.0,7:6.0,8:7.0,9:8.0,10:9.0,},
"2":{0:np.nan,1:np.nan,2:0.0,3:1.0,4:2.0,5:3.0,6:4.0,7:5.0,8:6.0,9:7.0,10:8.0,},
"3":{0:np.nan,1:np.nan,2:np.nan,3:0.0,4:1.0,5:2.0,6:3.0,7:4.0,8:5.0,9:6.0,10:7.0,},
"4":{0:np.nan,1:np.nan,2:np.nan,3:np.nan,4:0.0,5:1.0,6:2.0,7:3.0,8:4.0,9:5.0,10:6.0,},
"5":{0:np.nan,1:np.nan,2:np.nan,3:np.nan,4:np.nan,5:0.0,6:1.0,7:2.0,8:3.0,9:4.0,10:5.0,},
"6":{0:np.nan,1:np.nan,2:np.nan,3:np.nan,4:np.nan,5:np.nan,6:0.0,7:1.0,8:2.0,9:3.0,10:4.0,},
"7":{0:np.nan,1:np.nan,2:np.nan,3:np.nan,4:np.nan,5:np.nan,6:np.nan,7:0.0,8:1.0,9:2.0,10:3.0,},
"8":{0:np.nan,1:np.nan,2:np.nan,3:np.nan,4:np.nan,5:np.nan,6:np.nan,7:np.nan,8:0.0,9:1.0,10:2.0,},
"9":{0:np.nan,1:np.nan,2:np.nan,3:np.nan,4:np.nan,5:np.nan,6:np.nan,7:np.nan,8:np.nan,9:0.0,10:1.0,},
"10":{0:np.nan,1:np.nan,2:np.nan,3:np.nan,4:np.nan,5:np.nan,6:np.nan,7:np.nan,8:np.nan,9:np.nan,10:0.0,},
}
)
fig=plt.figure(figsize=(8,3))
ax1=fig.add_subplot(121, projection="3d")
ax2=fig.add_subplot(122, projection="3d")
#thickness of the bars
dx, dy = 1, 1
# set up positions for the bars
xpos = np.arange(data1.shape[0])
ypos = np.arange(data1.shape[1])
# create meshgrid
# print xpos before and after this block if not clear
xpos, ypos = np.meshgrid(xpos, ypos)
xpos = xpos.flatten()
ypos = ypos.flatten()
# the bars starts from 0 attitude
zpos = np.zeros(data1.shape).flatten()
# the bars' heights
dz1 = data1.values.ravel()
dz2 = data2.values.ravel()
ma = np.nanmax(data1.values)
norm = matplotlib.colors.Normalize(vmin=0, vmax=10, clip=True)
# # plot
ax1.bar3d(xpos, ypos, zpos, dx, dy, dz1, shade=True, ec="k", lw=0.1)
ax2.bar3d(xpos, ypos, zpos, dx, dy, dz2, shade=True, ec="k", lw=0.1)
# set up the axes furniture
for ax in [ax1, ax2]:
ax.set_xticks(xpos + dx / 2)
ax.set_yticks(ypos + dy / 2)
ax.w_yaxis.set_ticklabels([])
ax.w_xaxis.set_ticklabels([])
ax.w_zaxis.set_ticklabels([])
ax.set_zlim(0, 10.5)
ax.set_xlim(0, 10.5)
ax.set_ylim(0, 10.5)
# name the axes
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("z")
plt.show()
It results in a figure that looks like this:
The graph on the left shows everything in the right place (though you might have to run the code and rotate the graph to see for yourself) but the one on the right plots the bars out of sequence and we end up with something a bit... odd.
My question is
- what's going on here, and
- is there any way of fixing this within matplotlib, if so how?
Thanks!