bar3d 图中的错误重叠

问题描述 投票:0回答:2

我已经制作了这个 3d 条形图,但我发现某些条形图中存在错误的重叠,如下图所示,用绿色圆圈表示:

情节制作者:

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

fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111, projection='3d')    
matrix = np.array([
[84 80 68 56 60 44 55 39 27 29]
[82 67 63 44 47 33 22 19  9  2]
[53 61 48 34  0 16  0  0  0  0]
[48 25  0  0  0  0  0  0  0  0]])

len_x, len_y = matrix.shape
_x = np.arange(len_x)
_y = np.arange(len_y)

xpos, ypos = np.meshgrid(_x, _y)
xpos = xpos.flatten('F')
ypos = ypos.flatten('F')
zpos = np.zeros_like(xpos)

dx = np.ones_like(zpos)
dy = dx.copy()
dz = matrix.flatten()

cmap=plt.cm.magma(plt.Normalize(0,100)(dz))

ax.bar3d(xpos+0.32, ypos-0.3, zpos, dx-0.6, dy-0.1, dz, zsort='max', color=cmap)

ax.set_xlabel('x')
ax.set_xticks(np.arange(len_x+1))
ax.set_xticklabels(['1000','500','100','50','0'])
ax.set_xlim(0,4)
ax.set_ylabel('y')
ax.set_yticks(np.arange(len_y+1))
ax.set_yticklabels(['0.5','1.','1.5','2.','2.5','3.','3.5','4.','4.5','5.'])
ax.set_ylim(-0.5,10)
ax.set_zlabel('z')
ax.set_zlim(0,100)
ax.view_init(ax.elev, ax.azim+100)

这是一个错误吗?为什么有些条形严重重叠? 我正在使用 matplotlib 版本 2.1.0 和 anaconda python 3.6.3

python matplotlib 3d
2个回答
1
投票

正如@DavidG 在评论中指出的,这是一个没有理想解决方案的问题:

我的 3D 绘图在某些视角下看起来不正确
这可能是 mplot3d 最常报告的问题。问题是 从某些视角来看,一个 3D 物体会出现在您的面前 另一个物体,即使它实际上位于它的后面。这个可以 导致绘图看起来“物理上不正确”。

不幸的是,虽然我们正在做一些工作来减少这种情况的发生 这个神器,目前是一个棘手的问题,无法 直到 matplotlib 支持 3D 图形渲染 核心。
[来源]

但是,通过调整图的视角并减少条之间的接触面积,我能够大大减少这个问题。

例如,要更改视角(“相机位置”),我使用:

ax.view_init(elev=30, azim=-60) # Changes the elevation and azimuth

更多详细信息请参阅如何使用 python/matplotlib 设置 3D 绘图的“相机位置”?

至于接触面积,这取决于你的地块。就我而言,所有条形都沿着 y 轴接触,因此我只是稍微减少了

dy
参数,以在条形之间留下一些间隙。


0
投票

我将其设为一个相对通用的函数,它接受 DataFrame 并绘制它。 这与原来的问题无关,但仍然有用。

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

def plot_3d_bar(df):
    y_labels = list(df.columns)
    x_labels = list(df.index.to_series())
    fig = plt.figure(figsize=(10,8))
    ax = fig.add_subplot(111, projection='3d')

    matrix = df.values
    len_x, len_y = matrix.shape
    _x = np.arange(len_x)
    _y = np.arange(len_y)

    xpos, ypos = np.meshgrid(_x, _y)
    xpos = xpos.flatten('F')
    ypos = ypos.flatten('F')
    zpos = np.zeros_like(xpos)

    dx = np.ones_like(zpos)
    dy = dx.copy()
    dz = matrix.flatten()
    cmap=plt.cm.magma(plt.Normalize(0,max(dz))(dz))

    ax.bar3d(xpos+0.32, ypos-0.3, zpos, dx-0.6, dy-0.6, dz, zsort='max', color=cmap)
    
    ax.set_xlabel('x')
    ax.set_xticks(np.arange(len_x))
    ax.set_xticklabels(x_labels)
    ax.set_xlim(0, len_x)

    ax.set_ylabel('y')
    ax.set_yticks(np.arange(len_y))
    ax.set_yticklabels(y_labels)
    ax.set_ylim(-0.5, len_y)

    ax.set_zlabel('z')
    #ax.set_zlim(0,3000)

    ax.view_init(elev=30, azim=-60)

    plt.show()
© www.soinside.com 2019 - 2024. All rights reserved.