【问题标题】:Is it possible to superimpose 3-d bar charts in matplotlib?是否可以在 matplotlib 中叠加 3-d 条形图?
【发布时间】:2016-05-16 18:23:06
【问题描述】:

本质上是这个的 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()

【问题讨论】:

    标签: python numpy matplotlib mplot3d


    【解决方案1】:

    您已经解决了一半的问题,因为第一个棘手的问题是使用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 的面孔前面。它可能特定于正在使用的后端:我正在使用 Qt4Agg 后端从ipython 运行它。这也让我可以围绕情节旋转,在这种情况下,很明显这种方法存在致命的渲染问题。这是一张静止图像:

    您可以在左起第二个条形图上看到,该条形图后面的零级补丁似乎位于该条形图的顶部补丁之前。显然不是你(或任何人,就此而言)需要的。

    经过一些试验(以及来自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()
    

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

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

    【讨论】:

    • 谢谢。关于如何进行切割有什么建议吗?
    • @M.Vasalakis 作为第一次尝试,我会将两个数据集的 xposypos 移动 +-0.25,同时更改 dx 或 @ 987654340@(取决于您选择的xpos/ypos 至 0.25。
    • 我试过了,它看起来更糟。肯定有某种错误,因为深度感知变得很奇怪。
    • @M.Vasalakis 恐怕我只能确认。我试过玩弄绘图顺序和其他东西,不能让它变得更好。也许在zorder 的酒吧里玩耍会影响到这一点……我不知道。
    • 所有期望的都是白色的,黑色的轮廓,每行用不同的颜色填充。
    猜你喜欢
    • 2015-12-25
    • 2020-11-02
    • 2019-05-30
    • 1970-01-01
    • 1970-01-01
    • 2014-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多