首页 > 解决方案 > 使用 matplotlib 绘制的 3d 对象的顺序

问题描述

我想想象一艘穿过海浪的船。我使用 plot_surface 绘制海面,船是 3d 补丁的集合。无论我如何设置元素的顺序,它们总是以 3d 表面覆盖船的方式出现。我希望船更显眼。尝试了 plot_wireframe 而不是表面,但线条仍然在顶部。有任何想法吗?

import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d as mp3d

L=180 # wavelength
Nx=256
dx=4.0*L/Nx
kxi=int(Nx*dx/L)
kx=2*np.pi*kxi/dx/Nx
L=2*np.pi/kx
omega=np.sqrt(9.81*2*np.pi/L)
ship_nodes=20*(np.array([[0,0,0],[-5,-2,-1],[-5,-2,1],[5,-2,1],[5,-2,-1],[-5,2,-1],[-5,2,1],[5,2,1],[5,2,-1],[7,0,-1],[7,0,1]],dtype=np.float32))+np.array([Nx*dx/2,Nx*dx/2,0])
x=ship_nodes
ship_planes=[x[1:5],x[5:9],x[[2,6,7,3]],x[[1,4,8,5]],x[[1,2,6,5]],x[[3,10,7]],x[[4,9,8]],x[7:11],x[[3,4,9,10]]]
X,Y=np.meshgrid(np.linspace(0,Nx*dx,Nx),np.linspace(0,Nx*dx,Nx))
A=np.zeros((Nx,Nx),dtype=np.complex64)
A[int(Nx/2)+kxi,int(Nx/2)]=10.0j
Z=np.real(np.fft.ifftn(np.fft.ifftshift(A), axes=(0, 1))*(Nx*Nx))
fig=plt.figure('Ship')
ax=mp3d.Axes3D(fig)
p=mp3d.art3d.Poly3DCollection(ship_planes,zorder=10)
p.set_facecolor((0,0.5,0))
p.set_edgecolor('k')
p.set_zorder(10)
p1=ax.plot_surface(X,Y,Z.T,zorder=1,lw=1)
p1.set_zorder(1)
c1=ax.add_collection3d(p1)
c2=ax.add_collection3d(p)
ax.set_xlim3d(0,Nx*dx)
ax.set_ylim3d(0,Nx*dx)
ax.set_zlim3d(-Nx*dx/2,Nx*dx/2)
fig.show()

图片示例

标签: pythonmatplotlib

解决方案


zorder似乎在这里不起作用。一种方法是使用 使波面有点透明alpha。此外,您不需要添加c1=ax.add_collection3d(p1)到代码中,因为ax.plot_surface已经将曲面添加到绘图中

p=mp3d.art3d.Poly3DCollection(ship_planes)
p.set_facecolor((0,0.5,0))
p.set_edgecolor('k')
p1=ax.plot_surface(X,Y,Z.T,lw=1, alpha=0.7)
c2=ax.add_collection3d(p)

在此处输入图像描述


推荐阅读