使用Matplotlib渲染3D立方体时出错

时间:2018-10-09 17:00:21

标签: python matplotlib 3d

我想使用matplotlib渲染3D立方体。 呈现了多维数据集,但从某些方向看时有毛刺:enter image description here

从正面看时,洋红色的一面正在渗入。 我该如何解决?

这是我的代码:

import numpy as np
import math
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection

a=0.5
cube = np.array([
[-a,-a,-a], \
[+a,-a,-a], \
[+a,+a,-a], \
[-a,+a,-a], \
            \
[-a,-a,+a], \
[+a,-a,+a], \
[+a,+a,+a], \
[-a,+a,+a]  \
])

bottom = [0,1,2,3]
top    = [4,5,6,7]
front  = [0,1,5,4]
right  = [1,2,6,5]
back   = [2,3,7,6]
left   = [0,3,7,4]

def rotation(theta = np.random.random_sample(3) * math.pi * 2, R = np.zeros((3,3))):
    cx,cy,cz = np.cos(theta)
    sx,sy,sz = np.sin(theta)
    R.flat = (cx*cz - sx*cy*sz, cx*sz + sx*cy*cz, sx*sy,
        -sx*cz - cx*cy*sz, -sx*sz + cx*cy*cz,
        cx*sy, sy*sz, -sy*cz, cy)
    return R 

def render_rotation(rot):
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.view_init(elev=0, azim=0)
    ax.grid(False)
    plt.axis('off')
    ax.set_proj_type('persp')
    # rotate cube
    rotated=np.linalg.linalg.dot(rotation(rot), cube.transpose()).transpose()
    def render_side(idx, clr):
        ax.add_collection3d(Poly3DCollection([
            [rotated[idx[0]]+a, rotated[idx[1]]+a, rotated[idx[2]]+a, rotated[idx[3]]+a]
        ], facecolors=clr, linewidths=0)) 
    render_side(top   , 'red')
    render_side(front , 'green')
    render_side(right , 'blue')
    render_side(bottom, 'cyan')
    render_side(back  , 'magenta')
    render_side(left  , 'yellow')
    plt.show()
    plt.close()
render_rotation(np.array([0,0,0]))

编辑: 解决方案ImportanceOfBeingErnest的评论。

我只需要稍微更改我的渲染功能:

clrs=[]
verts=[]
def render_side(idx, clr):
    clrs.append(clr)
    verts.append([
        rotated[idx[0]]+a, 
        rotated[idx[1]]+a, 
        rotated[idx[2]]+a, 
        rotated[idx[3]]+a])
render_side(top   , 'red')
render_side(front , 'green')
render_side(right , 'blue')
render_side(bottom, 'cyan')
render_side(back  , 'magenta')
render_side(left  , 'yellow')
ax.add_collection3d(Poly3DCollection(verts, facecolors=clrs, linewidths=0)) 

1 个答案:

答案 0 :(得分:0)

ImportanceOfBeingErnest的评论是解决方案。 render_rotation的修复程序仅使用一个Poly3DCollection

def render_rotation(rot):
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.view_init(elev=0, azim=0)
    ax.grid(False)
    plt.axis('off')
    ax.set_proj_type('persp')
    # rotate cube
    clrs=[]
    verts=[]
    def render_side(idx, clr):
        clrs.append(clr)
        verts.append([
            rotated[idx[0]]+a, 
            rotated[idx[1]]+a, 
            rotated[idx[2]]+a, 
            rotated[idx[3]]+a])
    render_side(top   , 'red')
    render_side(front , 'green')
    render_side(right , 'blue')
    render_side(bottom, 'cyan')
    render_side(back  , 'magenta')
    render_side(left  , 'yellow')
    ax.add_collection3d(Poly3DCollection(verts, facecolors=clrs, linewidths=0)) 
    plt.show()
    plt.close()