【问题标题】:Center 3D bars on the given positions in matplotlib在 matplotlib 中的给定位置居中 3D 条
【发布时间】:2018-09-19 09:03:11
【问题描述】:

考虑使用自定义网格线的 3D 条形图:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from matplotlib.ticker import MultipleLocator
# This import registers the 3D projection, but is otherwise unused.
from mpl_toolkits.mplot3d import Axes3D  # noqa: F401 unused import

fig = plt.figure(figsize=(20, 10))
ax = fig.add_subplot(111, projection='3d')

ax.xaxis.set_major_locator(MultipleLocator(1))
ax.yaxis.set_major_locator(MultipleLocator(1))
ax.zaxis.set_major_locator(MultipleLocator(2))

nx = 10
ny = 10

colors = cm.tab20(np.linspace(0, 1, nx))
width = depth = 0.1

for x in np.arange(nx):
    for y in np.arange(ny):
        ax.bar3d(x, y, 0, width, depth, x+y, shade=False, color = colors[x], edgecolor = 'black')

plt.show()

如何放置条形图,使条形图位于 xy 平面中网格线相互交叉的中心?

我正在考虑类似的事情

ax.bar3d(x+0.5*depth, y+0.5*width, ...)

只是我不清楚 matplotlib 使用什么偏移量。它应该适用于所有 depthwidth 值。

对于 2D 条形图,有一个参数 align = 'center',但它似乎不适用于 3D。

【问题讨论】:

    标签: python matplotlib 3d bar-chart


    【解决方案1】:

    在您看来,坐标的变化实际上只是与轴边距相结合的投影。因此,即使条形图正确定位在它们的中心,它们看起来也是偏移的,而偏移量取决于轴的大小、视角等。

    这个问题的解决方案原则上在这个问答中给出: Removing axes margins in 3D plot

    您可以通过减去一半宽度来使条居中,并添加一个补丁来移除 z 轴的边距。然后将 z 下限设置为 0 将条形固​​定到网格上,并使它们在任何视角下看起来都居中。

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.cm as cm
    from matplotlib.ticker import MultipleLocator
    from mpl_toolkits.mplot3d import Axes3D 
    from mpl_toolkits.mplot3d.axis3d import Axis
    
    def _get_coord_info_new(self, renderer):
        mins, maxs, cs, deltas, tc, highs = self._get_coord_info_old(renderer)
        correction = deltas * [0,0,1.0/4]
        mins += correction
        maxs -= correction
        return mins, maxs, cs, deltas, tc, highs
    if not hasattr(Axis, "_get_coord_info_old"):
        Axis._get_coord_info_old = Axis._get_coord_info  
    Axis._get_coord_info = _get_coord_info_new
    
    
    fig = plt.figure(figsize=(20, 10))
    ax = fig.add_subplot(111, projection='3d')
    
    ax.xaxis.set_major_locator(MultipleLocator(1))
    ax.yaxis.set_major_locator(MultipleLocator(1))
    ax.zaxis.set_major_locator(MultipleLocator(2))
    
    nx = 10
    ny = 10
    
    colors = cm.tab20(np.linspace(0, 1, nx))
    width = depth = 0.1
    
    for x in np.arange(nx):
        for y in np.arange(ny):
            ax.bar3d(x-width/2., y-depth/2., 0, width, depth, x+y, shade=False, 
                     color = colors[x], edgecolor = 'black')
    
    ax.set_zlim(0,None)
    
    plt.show()
    

    【讨论】:

    • 谢谢。这个解决方案比我预期的要复杂,但我想它就是这样。这对您有意义吗,即您是否理解他们为什么选择不让条形图从 z = 0 开始?
    • 我只能在这里猜测,但似乎轴的自动边距是在没有像条形图这样的情况下引入的,应该牢记在平面上。
    猜你喜欢
    • 1970-01-01
    • 2017-07-08
    • 1970-01-01
    • 1970-01-01
    • 2012-03-15
    • 1970-01-01
    • 2012-02-19
    • 2015-10-26
    • 1970-01-01
    相关资源
    最近更新 更多