是否可以在 matplotlib 中叠加 3-d 条形图?
Is it possible to superimpose 3-d bar charts in matplotlib?
本质上是这个的 3d 版本:Plot two histograms at the same time with 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()
您已经解决了一半的问题,因为第一个棘手的问题是使用 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)
然而,这会产生丑陋和不需要的结果,即 z==0
处的某些面孔似乎呈现在 z>0
处的面孔前面。它可能特定于正在使用的后端:我是 运行 来自 ipython
的 Qt4Agg 后端。这也允许我围绕情节旋转,在这种情况下,很明显这种方法存在致命的渲染问题。这是一张静止图像:
您可以在左数第二个条形图上看到,条形图后面 的零级补丁似乎在条形图顶部补丁的前面。显然不是您(或任何人)所需要的。
经过一些试验(以及来自 this answer 的有用提示)我意识到 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.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()
当使用交互式后端旋转此图时,很明显它的行为几乎完美(尽管从某些观察方向来看仍然存在小故障)。这是固定解决方案的静止图像:
最后,请注意,即使没有渲染故障,也不是很容易理解这种重叠的条形图。您 link 在您的问题中遇到的 2d 情况可以解决,因为两个凸起明显分开。如果它们有很大的重叠,那么情节就会更难理解。我建议考虑其他可视化方式,例如将每个条形图分成两部分(每个条形图都有一个垂直平面)并在每个位置并排绘制两组 z
数据。
本质上是这个的 3d 版本:Plot two histograms at the same time with 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()
您已经解决了一半的问题,因为第一个棘手的问题是使用 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)
然而,这会产生丑陋和不需要的结果,即 z==0
处的某些面孔似乎呈现在 z>0
处的面孔前面。它可能特定于正在使用的后端:我是 运行 来自 ipython
的 Qt4Agg 后端。这也允许我围绕情节旋转,在这种情况下,很明显这种方法存在致命的渲染问题。这是一张静止图像:
您可以在左数第二个条形图上看到,条形图后面 的零级补丁似乎在条形图顶部补丁的前面。显然不是您(或任何人)所需要的。
经过一些试验(以及来自 this answer 的有用提示)我意识到 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.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()
当使用交互式后端旋转此图时,很明显它的行为几乎完美(尽管从某些观察方向来看仍然存在小故障)。这是固定解决方案的静止图像:
最后,请注意,即使没有渲染故障,也不是很容易理解这种重叠的条形图。您 link 在您的问题中遇到的 2d 情况可以解决,因为两个凸起明显分开。如果它们有很大的重叠,那么情节就会更难理解。我建议考虑其他可视化方式,例如将每个条形图分成两部分(每个条形图都有一个垂直平面)并在每个位置并排绘制两组 z
数据。