是否可以在matplotlib中叠加3-d条形图?

M.V*_*.V. 5 python numpy matplotlib mplot3d

本质上是3d版本:使用matplotlib同时绘制两个直方图

尽管由于使用Axes 3d,所以我不知道该怎么做。

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

kets = ["|00>","|01>","|10>","|11>"] #my axis labels

fig = plt.figure()
ax1  = fig.add_subplot(111,projection = '3d')

xpos = [0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3]
xpos = [i+0.25 for i in xpos]
ypos = [0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3]
ypos = [i+0.25 for i in ypos]
zpos = [0]*16

dx    = 0.5*np.ones(16)
dy    = 0.5*np.ones(16)
dz    = [1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0]
dz2   = [0.2*i for i in dz] # to superimpose dz

ticksx = np.arange(0.5,4,1)
ticksy = np.arange(0.6,4,1)

ax1.bar3d(xpos, ypos, zpos, dx , dy ,dz,  color = '#ff0080', alpha = 0.5)

ax1.w_xaxis.set_ticklabels(kets)
ax1.w_yaxis.set_ticklabels(kets)
ax1.set_zlabel('Coefficient')

plt.xticks(ticksx,kets)
plt.yticks(ticksy,kets)

plt.show()
Run Code Online (Sandbox Code Playgroud)

And*_*eak 5

您已经解决了一半的问题,因为第一个棘手的部分是将条形图设置为半透明alpha=0.5。但还有一个更微妙的问题需要注意。

第一个天真的尝试是将您的调用复制bar3d到其他数据集。这应该有效,并且在某种程度上确实有效。您的条形图彼此完全重叠(dz2非零值全部包含在 中的高条形图中dz),因此我建议使较小的条形不太透明,而较高的条形更加透明,如下所示:

# less transparent
ax1.bar3d(xpos, ypos, zpos, dx , dy ,dz,  color = '#ff0080', alpha = 0.3)
# use dz2, fully opaque, and bluish
ax1.bar3d(xpos, ypos, zpos, dx , dy ,dz2,  color = '#008080', alpha = 1)
Run Code Online (Sandbox Code Playgroud)

然而,这会产生丑陋且不想要的结果,即 处的一些面孔z==0似乎渲染在 处的面孔前面z>0。它可能特定于所使用的后端:我正在ipython使用 Qt4Agg 后端运行它。这也允许我围绕绘图旋转,在这种情况下,很明显这种方法存在致命的渲染问题。这是一张静态图像:

存在渲染问题的图像

您可以在左侧第二个条上看到,条后面的零电平补丁似乎位于条顶部补丁的前面。显然不是您(或任何人)需要的。

经过一些实验(以及这个答案的有用提示),我意识到bar3d同时绘制多个条形图时这只是错误的。解决方法很简单:使用循环逐个创建每个条,问题(几乎完全)消失:

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

kets = ["|00>","|01>","|10>","|11>"] #my axis labels

fig = plt.figure()
ax1  = fig.add_subplot(111,projection = '3d')

xpos = [0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3]
xpos = [i+0.25 for i in xpos]
ypos = [0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3]
ypos = [i+0.25 for i in ypos]
zpos = [0]*16

dx    = 0.5*np.ones(16)
dy    = 0.5*np.ones(16)
dz    = [1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0]
dz2   = [0.2*i for i in dz] # to superimpose dz

ticksx = np.arange(0.5,4,1)
ticksy = np.arange(0.6,4,1)

# only change here:
# new loop, changed alphas and a color
for k in range(len(xpos)):
    ax1.bar3d(xpos[k], ypos[k], zpos[k], dx[k] , dy[k] ,dz[k],  color = '#ff0080', alpha = 0.3)
    ax1.bar3d(xpos[k], ypos[k], zpos[k], dx[k] , dy[k] ,dz2[k],  color = '#008080', alpha = 1)


ax1.xaxis.set_ticklabels(kets)
ax1.yaxis.set_ticklabels(kets)
ax1.set_zlabel('Coefficient')

plt.xticks(ticksx,kets)
plt.yticks(ticksy,kets)

plt.show()
Run Code Online (Sandbox Code Playgroud)

当使用交互式后端旋转该图时,很明显它的行为几乎完美(尽管从某些观看方向来看仍然存在一些小故障)。这是固定解决方案的静止图像:

固定条形图

最后,请注意,即使没有渲染故障,理解这种重叠的条形图也不是很容易。您在问题中链接到的第二个案例可以逃脱它,因为两个凹凸是明显分开的。如果它们有很大的重叠,那么情节就更难理解了。我建议考虑其他可视化方式,例如将每个条形切割成两个(每个条形有一个垂直平面)并z在每个位置并排绘制两组数据。