Python 如何使用Matplotlib正确绘制叠加的三维条形图?

Python 如何使用Matplotlib正确绘制叠加的三维条形图?,python,matplotlib,plot,Python,Matplotlib,Plot,我正在使用Matplotlib中的bar3d绘制3D直方图数据。我想在同一个图上绘制实际数据和参考。我使用的技术类似于中的一种,包括在同一轴上叠加条 这里有一个复制问题的最小脚本 导入matplotlib.pyplot作为plt 从mpl_toolkits.mplot3d导入Axes3D 值=0.7 对于i,枚举中的值_引用([0.66,0.5]): 图=plt.图() 图suptitle('value='+str(value)+',reference='+str(value_reference

我正在使用Matplotlib中的
bar3d
绘制3D直方图数据。我想在同一个图上绘制实际数据和参考。我使用的技术类似于中的一种,包括在同一轴上叠加条

这里有一个复制问题的最小脚本

导入matplotlib.pyplot作为plt
从mpl_toolkits.mplot3d导入Axes3D
值=0.7
对于i,枚举中的值_引用([0.66,0.5]):
图=plt.图()
图suptitle('value='+str(value)+',reference='+str(value_reference))
#条形图和参考条形图之间的间距
s=0.05
#参考杆的厚度
δ=0.01
#准备三维轴
轴=图gca(投影='3d')
#制作指示该值的内条
axes.bar3d(
s/2.,s/2.,0.,1.-s,1.-s,值,
edgecolor='black')
#用指示参考的外条将其环绕
axes.bar3d(
0,0.,参考值-δ/2,1,1,δ,
颜色=(0,0,1,0),
edgecolor='black')
#plt.show()
图savefig('plot_reference_'+str(i)+'.png')
下面是这个脚本的结果图

正如你所看到的,总是一根杠遮住了另一根杠。在第一种情况下,我们可以看到该条后面的参考标高,该标高通常应包含在该条中。在第二种情况下,我们根本看不到参考级别,因为它完全由条形图覆盖

我认为这样做的原因是Matplotlib一个接一个地绘制整个条形图(就像脚本中所做的那样)。是否有方法向Matplotlib指示这两条线是重叠的,它们的面应按特定顺序绘制

用于生成这些图的环境

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.14.5
BuildVersion:   18F132
Python版本

$ python -V
Python 3.7.4
Matplotlib版本

$ pip show matplotlib
Name: matplotlib
Version: 3.1.2
Summary: Python plotting package
Home-page: https://matplotlib.org
Author: John D. Hunter, Michael Droettboom
Author-email: matplotlib-users@python.org
License: PSF
Location: /Users/marek/.pyenv/versions/3.7.4/lib/python3.7/site-packages
Requires: kiwisolver, cycler, pyparsing, python-dateutil, numpy
Required-by: 

第一个
3D
绘图隐藏了另一个。这是你的解决方案吗

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

value = 0.7
for i, value_reference in enumerate([0.66, 0.5]):
    fig = plt.figure()
    fig.suptitle('value = ' + str(value) + ', reference = ' + str(value_reference))
    # space between bar and reference bar
    s = 0.05
    # thickness of reference bar
    delta = 0.02
    # prepare 3D axis
    axes = fig.gca(projection='3d')
    # make the inner bar indicating the value
    axes.bar3d(
        0., 0., value_reference - delta/2., 1., 1., delta, color='r', alpha=0.2,
        edgecolor='black')
    axes.bar3d(
        s/2., s/2., 0., 1.-s, 1.-s, value, color='b',alpha=0.2,
        edgecolor='black')
    # surround it with outer bar indicating the reference

    plt.show()
这清楚地显示了两个图:


我不确定你是否可以让matplot按照特定的顺序进行绘图。这似乎是关于zorder的热门讨论。您可以在此处阅读更多内容

第一个
3D
绘图隐藏了另一个。这是你的解决方案吗

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

value = 0.7
for i, value_reference in enumerate([0.66, 0.5]):
    fig = plt.figure()
    fig.suptitle('value = ' + str(value) + ', reference = ' + str(value_reference))
    # space between bar and reference bar
    s = 0.05
    # thickness of reference bar
    delta = 0.02
    # prepare 3D axis
    axes = fig.gca(projection='3d')
    # make the inner bar indicating the value
    axes.bar3d(
        0., 0., value_reference - delta/2., 1., 1., delta, color='r', alpha=0.2,
        edgecolor='black')
    axes.bar3d(
        s/2., s/2., 0., 1.-s, 1.-s, value, color='b',alpha=0.2,
        edgecolor='black')
    # surround it with outer bar indicating the reference

    plt.show()
这清楚地显示了两个图:


我不确定你是否可以让matplot按照特定的顺序进行绘图。这似乎是关于zorder的热门讨论。你可以在这里阅读更多内容

谢谢你的反馈@SSharma,这是一种有趣的可视化水平的方式,不幸的是,这不是我希望重现的风格,因此我不能接受你的答案作为解决方案,但我很高兴你发布了它,因为我相信很多人在他们的情节中可能需要这种风格。是的,zorder的讨论已经有一段时间了,我也亲自尝试过。但它不适用于
bar3d
。我必须说,这仍然是一个bug。谢谢你的反馈@SSharma,这是一个可视化级别的有趣方式,不幸的是,这不是我希望重新创建的样式,所以我不能接受你的答案作为解决方案,但我很高兴你发布了它,因为我相信很多人在他们的情节中可能需要这种样式。是的,zorder的讨论已经有一段时间了,我也亲自尝试过。但它不适用于
bar3d
。我必须说,这仍然是一个错误。