如果高度为零,Matplotlib 在 bar3d 中隐藏栏
Posted
技术标签:
【中文标题】如果高度为零,Matplotlib 在 bar3d 中隐藏栏【英文标题】:Matplotlib hide bar in bar3d if height is zero 【发布时间】:2022-01-08 18:48:46 【问题描述】:我见过matplotlib invisible bar if height is zero - 但是,这是针对二维条形图的情况,所以我无法将其完全应用于我的问题。
我还看到了Make transparent color bar with height 0 in matplotlib,它应该可用于 3D 案例 - 但是,我不想让零高度条透明,我想隐藏它们,以在交互(旋转)时加快渲染速度3D 绘图。
这是一个示例,基于Create 3D histogram of 2D data — Matplotlib 3.5.0 documentation:
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
x = y = np.concatenate([np.array([5,4,3,2,1]), np.zeros(35)])
hist, xedges, yedges = np.histogram2d(x, y, bins=40, range=[[0, 40], [0, 40]])
# Construct arrays for the anchor positions of the 16 bars.
xpos, ypos = np.meshgrid(xedges[:-1] + 0.25, yedges[:-1] + 0.25, indexing="ij")
xpos = xpos.ravel()
ypos = ypos.ravel()
zpos = 0
# Construct arrays with the dimensions for the 16 bars.
dx = dy = 0.5 * np.ones_like(zpos)
dz = hist.ravel()
ax.bar3d(xpos, ypos, zpos, dx, dy, dz, zsort='average')
plt.show()
运行它会创建这个情节:
大多数条形图的高度为 0,但数量很多,因此旋转图有点慢。
我曾尝试像这样“屏蔽”,如Make transparent color bar with height 0 in matplotlib:
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
x = y = np.concatenate([np.array([5,4,3,2,1]), np.zeros(35)])
hist, xedges, yedges = np.histogram2d(x, y, bins=40, range=[[0, 40], [0, 40]])
# Construct arrays for the anchor positions of the 16 bars.
xpos, ypos = np.meshgrid(xedges[:-1] + 0.25, yedges[:-1] + 0.25, indexing="ij")
xpos = xpos.ravel()
ypos = ypos.ravel()
zpos = 0
# Construct arrays with the dimensions for the 16 bars.
dx = dy = 0.5 * np.ones_like(zpos)
dz = hist.ravel()
mask_dz = dz == 0 # SO:60111736, 3d case
ax.bar3d(xpos[~mask_dz], ypos[~mask_dz], zpos[~mask_dz], dx[~mask_dz], dy[~mask_dz], dz[~mask_dz], zsort='average')
plt.show()
...但这失败了:
Traceback (most recent call last):
File "D:\msys64\tmp\test.py", line 22, in <module>
ax.bar3d(xpos[~mask_dz], ypos[~mask_dz], zpos[~mask_dz], dx[~mask_dz], dy[~mask_dz], dz[~mask_dz], zsort='average')
TypeError: 'int' object is not subscriptable
我怎样才能得到与前面所示相同的图 - 除了隐藏所有零高度条?
【问题讨论】:
【参考方案1】:在写这个问题的时候,我偶然发现了正确的解决方案——基本上,并不是所有的 xpos,... dx,... 都是数组,所以我们不应该在它们不存在的地方应用掩码:
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
x = y = np.concatenate([np.array([5,4,3,2,1]), np.zeros(35)])
hist, xedges, yedges = np.histogram2d(x, y, bins=40, range=[[0, 40], [0, 40]])
# Construct arrays for the anchor positions of the 16 bars.
xpos, ypos = np.meshgrid(xedges[:-1] + 0.25, yedges[:-1] + 0.25, indexing="ij")
xpos = xpos.ravel()
ypos = ypos.ravel()
zpos = 0
# Construct arrays with the dimensions for the 16 bars.
dx = dy = 0.5 * np.ones_like(zpos)
dz = hist.ravel()
mask_dz = dz == 0 # SO:60111736, 3d case
ax.bar3d(xpos[~mask_dz], ypos[~mask_dz], zpos, dx, dy, dz[~mask_dz], zsort='average')
# after the above command, the plot range xlim and ylim gets set to [0,6] - so re-set it back to same as on original image
ax.set_xlim([0, 40])
ax.set_ylim([0, 40])
plt.show()
...这个情节的结果:
...确实更容易与之交互。
请注意,应用蒙版后,绘图的 xlim 和 ylim 会重置为与 OP 中显示的范围不同的范围,因此需要重新应用范围,以获得与中相同的绘图范围可视化OP。
【讨论】:
以上是关于如果高度为零,Matplotlib 在 bar3d 中隐藏栏的主要内容,如果未能解决你的问题,请参考以下文章
$(document).ready() 内的 div 高度为零