matplotlib绘制李萨如图(四)
——动态3D李萨如图
1 前期回顾
老规矩,要绘制动态3D图,肯定要先会静态3D图。
由于FuncAnimation
函数貌似还只能用于2D图,所以我们在画3D图的时候只能另辟蹊径,使用交互模式。
2 主要函数
交互模式的使用很简单,只需要一组打开/关闭交互模式的函数和一些清除原先画面的函数就够了。
plt.ion()
打开交互模式。
plt.ioff()
关闭交互模式。
plt.clf()
清空figure()
出来的画布,前缀可以是plt
,也可以是figure
出来的画布的名字,如fig.clf()
。
fig=plt.figure()
plt.clf()
plt.cla()
清空单个图像,前缀可以为要清空的图像的名称,如axs.cla()。
fig=plt.figure()
axs=fig.add_subplot(111,projection='3d')
plt.pause()
暂停,单位为s。
3 完整代码
有了上述交互式的组件,我们只需要在plt.ion
和plt,ioff
中间按照要求自己编写程序即可。
根据查到的其他文章所说,在matplotlib中画图有两种显示模式:
(1)阻塞模式,即必须利用plt.show()显示图片,且图片关闭之前代码将阻塞在该行。
(2)交互模式,即plt.plot()后立马显示图片,且不阻塞代码的继续运行。
但是博主惊奇的发现,即使我注释掉了开/关交互式的语句,动图依然可以正常显示,复制了其他博主的代码注释掉对应语句后依然如此,这个问题在博主至今未解决,欢迎大神解答。
cla()
版本:
import matplotlib.pyplot as plt
import numpy as np
import time
import matplotlib.animation as animation
fig=plt.figure()
plt.ion()
theta=np.linspace(0,2*np.pi,1000)
p=3
q=3
n=1/2
m=5
axs=fig.add_subplot(111,projection='3d')
for p in range(1,m+1,1):
for q in range(1,m+1,1):
axs.cla()
x=np.sin(p*theta)
y=np.sin(q*theta+n*np.pi)
z=np.cos(p*theta)+np.cos(q*theta+n*np.pi)
axs.plot3D(x,y,z,'gray')
axs.text(0.15,-0.15,2,'p=%d'% p,ha='center',va='top',fontsize=12)
axs.text(-0.15,0.15,2,'q=%d'% q,ha='center',va='top',fontsize=12)
axs.view_init(0,45)
plt.pause(0.2)
plt.ioff()
plt.show()
clf()
版本:
import matplotlib.pyplot as plt
import numpy as np
import time
import matplotlib.animation as animation
fig=plt.figure()
#plt.ion()
theta=np.linspace(0,2*np.pi,1000)
p=3
q=3
n=1/2
m=5
for p in range(1,m+1,1):
for q in range(1,m+1,1):
plt.clf()
axs=fig.add_subplot(111,projection='3d')
axs.set(xlim=[-1,1],ylim=[-1,1],zlim=[-2,2],title='Lissajous-Figure-3D')
#n=2/m*i
x=np.sin(p*theta)
y=np.sin(q*theta+n*np.pi)
z=np.cos(p*theta)+np.cos(q*theta+n*np.pi)
axs.plot3D(x,y,z,'gray')
axs.text(0.15,-0.15,2,'p=%d'% p,ha='center',va='top',fontsize=12)
axs.text(-0.15,0.15,2,'q=%d'% q,ha='center',va='top',fontsize=12)
axs.view_init(0,45)
plt.pause(0.2)
#plt.ioff()
plt.show()