在matplotlib poly3D中舍入圆柱的边缘

时间:2016-04-17 11:28:36

标签: python matplotlib

我有以下代码,它使用matplotlib生成一个类似圆柱体的对象:

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import numpy as np


fig = plt.figure()
ax = fig.gca(projection='3d')

nphi,nz=7,20
r=1 # radius of cylinder
phi = np.linspace(0,360, nphi)/180.0*np.pi
z= np.linspace(0,1.0,nz)
print z


cols=[]
verts2 = []
for i  in range(len(phi)-1):
    cp0= r*np.cos(phi[i])
    cp1= r*np.cos(phi[i+1])
    sp0= r*np.sin(phi[i])
    sp1= r*np.sin(phi[i+1])

    for j in range(len(z)-1):
        z0=z[j]
        z1=z[j+1]
        verts=[]
        verts.append((cp0, sp0, z0))
        verts.append((cp1, sp1, z0))
        verts.append((cp1, sp1, z1))
        verts.append((cp0, sp0, z1))
        verts2.append(verts)
        value=np.random.rand()
        #print value
        col=plt.cm.rainbow(0.9)
        #print col
        cols.append(col)

poly3= Poly3DCollection(verts2, facecolor=cols,edgecolor = "none"  )  

poly3.set_alpha(0.8)
ax.add_collection3d(poly3)
ax.set_xlabel('X')
ax.set_xlim3d(-1, 1)
ax.set_ylabel('Y')
ax.set_ylim3d(-1, 1)
ax.set_zlabel('Z')
ax.set_zlim3d(0, 1)
plt.show()

此代码生成以下图像:enter image description here

然而,你可以看到图中的尖角。反正是否要使这些边缘更圆,以使该图看起来像一个圆形横截面的正确圆柱体而不是六边形横截面?

1 个答案:

答案 0 :(得分:1)

第三个论点 np.linspace 控制您希望它生成多少个值。因此,nphi控制着 phinz中的值数量控制z中的值数量:

phi = np.linspace(0,360, nphi)/180.0*np.pi
z = np.linspace(0,1.0,nz)
  • 因此,如果您增加nphi,那么您将获得更多积分:

    cp0 = r*np.cos(phi[i])
    sp0 = r*np.sin(phi[i])
    

    例如,尝试将nphi, nz = 7,20更改为nphi, nz = 70, 2

  • 请注意,nz之后不需要大于2 圆柱体在z方向是平的。

  • 顺便说一句,双重for循环可以替换为:

    PHI, Z = np.meshgrid(phi, z)
    CP = r * np.cos(PHI)
    SP = r * np.sin(PHI)
    XYZ = np.dstack([CP, SP, Z])
    verts = np.stack(
        [XYZ[:-1, :-1], XYZ[:-1, 1:], XYZ[1:, 1:], XYZ[1:, :-1]], axis=-2).reshape(-1, 4, 3)
    

所以,例如,

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import numpy as np


fig = plt.figure()
ax = fig.gca(projection='3d')

nphi, nz = 70, 2
r = 1  # radius of cylinder
phi = np.linspace(0, 360, nphi) / 180.0 * np.pi
z = np.linspace(0, 1.0, nz)

PHI, Z = np.meshgrid(phi, z)
CP = r * np.cos(PHI)
SP = r * np.sin(PHI)
XYZ = np.dstack([CP, SP, Z])
verts = np.stack(
    [XYZ[:-1, :-1], XYZ[:-1, 1:], XYZ[1:, 1:], XYZ[1:, :-1]], axis=-2).reshape(-1, 4, 3)

cmap = plt.cm.rainbow
cols = cmap(np.random.random())
poly3 = Poly3DCollection(verts, facecolor=cols, edgecolor="none")

poly3.set_alpha(0.8)
ax.add_collection3d(poly3)
ax.set_xlabel('X')
ax.set_xlim3d(-1, 1)
ax.set_ylabel('Y')
ax.set_ylim3d(-1, 1)
ax.set_zlabel('Z')
ax.set_zlim3d(0, 1)
plt.show()

产量

enter image description here