我从Here获取以下代码,在此代码中,高度为2的图形由两个立方体(上部和下部)生成,我想要生成高度为2的图形,同样只有一个数字,同样身高3,4,5,......
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
def cuboid_data(center, N, size=(1,1,1)):
# code taken from
# https://stackoverflow.com/questions/30715083/python-plotting-a-wireframe-3d-cuboid?noredirect=1&lq=1
# suppose axis direction: x: to left; y: to inside; z: to upper
# get the (left, outside, bottom) point
o = [a - b / 2 for a, b in zip(center, size)]
l, w, h = size
x = [[o[0], o[0] + l, o[0] + l, o[0], o[0]], # x coordinate of points in bottom surface
[o[0], o[0] + l, o[0] + l, o[0], o[0]], # x coordinate of points in upper surface
[o[0], o[0] + l, o[0] + l, o[0], o[0]], # x coordinate of points in outside surface
[o[0], o[0] + l, o[0] + l, o[0], o[0]]] # x coordinate of points in inside surface
y = [[o[1], o[1], o[1] + w, o[1] + w, o[1]], # y coordinate of points in bottom surface
[o[1], o[1], o[1] + w, o[1] + w, o[1]], # y coordinate of points in upper surface
[o[1], o[1], o[1], o[1], o[1]], # y coordinate of points in outside surface
[o[1] + w, o[1] + w, o[1] + w, o[1] + w, o[1] + w]] # y coordinate of points in inside surface
z = [[0,0,0,0,0],
[N,N,N,N,N],
[0, 0, N,N, 0],
[0, 0, N, N, 0]]
return x, y, z
def plotCubeAt(pos=(0,0), N=0, ax=None):
# Plotting N cube elements at position pos
if ax !=None:
if N > 0:
#for n in range(N):
X, Y, Z = cuboid_data( (pos[0],pos[1],N),N )
ax.plot_surface(X, Y, Z, color='y', rstride=1, cstride=1)#,linewidth=0)
def plotIsoMatrix(ax, matrix):
# plot a Matrix
# where matrix[i,j] cubes are added at position (i,j)
for i in range(matrix.shape[0]):
for j in range(matrix.shape[1]):
plotCubeAt(pos=(i,j), N=matrix[i,j], ax=ax)
l = max(matrix.shape[0], matrix.shape[1], matrix.max())
#bb = np.array([(0,0,0), (0,l,0), (l,0,0), (l,l,0),(0,0,l), (0,l,l), (l,0,l), (l,l,l)])
#ax.plot(bb[:,0], bb[:,1], bb[:,2], "w", alpha=0.0)
if __name__ == '__main__':
fig = plt.figure()
ax = fig.gca(projection='3d')
#ax.set_aspect('equal')
matrix = np.array([[2,2],[1,2]])
plotIsoMatrix(ax, matrix)
#ax.set_axis_off()
plt.ion()
plt.show()
生成下图:
我想生成下图:
如何解决这个问题?
由于
答案 0 :(得分:2)
首先,如果你不想拥有单个立方体,而是想要长方体,那么有一个更简单的解决方案 - 使用matplotlib bar3d。
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_aspect('equal')
matrix = np.array([[2,2],[1,2]])
xpos, ypos = np.meshgrid(np.arange(matrix.shape[0]),np.arange(matrix.shape[1]) )
xpos = xpos.flatten('F')
ypos = ypos.flatten('F')
zpos = np.zeros_like(xpos)
dx = np.ones_like(zpos)
dy = dx.copy()
dz = matrix.flatten()
ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='y', zsort='average', linewidth=0)
l = max(matrix.shape[0], matrix.shape[1], matrix.max())
bb = np.array([(0,0,0), (0,l,0), (l,0,0), (l,l,0),(0,0,l), (0,l,l), (l,0,l), (l,l,l)])
ax.plot(bb[:,0], bb[:,1], bb[:,2], "w", alpha=0.0)
ax.set_axis_off()
plt.show()
关于长方体的重叠面,matplotlib中没有解决方案。我认为这种行为通常被认为是一个无法解决的问题,正如Matplotlib 3D FAQ中所述。此外,手动设置zorder将无法正常工作。然而,好消息是这种重叠与角度有关。因此,您总能找到一个可视角度(用鼠标旋转绘图),它看起来很好。
使用Mayavi,根本不存在重叠面的问题。此外,mayavi中的barchart
更方便,只需5行代码:
import numpy as np
import mayavi.mlab as mlab
mlab.figure(bgcolor=(1,1,1))
matrix = np.array([[2,2],[1,2]])
mlab.barchart(matrix, color=(1.,0.86, 0.12), lateral_scale=1.0)
mlab.show()