Rob*_*Tan 3 python math animation matplotlib matplotlib-animation
我尝试做一个非常简单的动画并用 matplotlib 保存它,但没有成功。例如,我想看到一些振荡的东西:这是我能做的最好的事情
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.animation as animation
#Define x,y vectors and meshgrid with function u on it
x = np.arange(0,10,0.1)
y = np.arange(0,10,0.1)
X,Y = np.meshgrid(x,y)
u = np.sin(X + Y)
#Create a figure and an axis object for the surface
#(which by the way is not initialized, because I don't know were to)
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
#Define a kind-of animation function, imitating what I saw many times
def animate(n):
global u
for n in (1,20):
u = np.sin((X + Y)*n)
return fig,
#I'm missing many commands, I'm just putting what I know
anim = animation.FuncAnimation(fig,animate)
anim.save('A.mp4',fps=10)
Run Code Online (Sandbox Code Playgroud)
我阅读了大量在线文档,包括官方文档,但我找不到表面随时间演变的清晰示例。我还发现很难掌握用 matplotlib 构建绘图背后的逻辑(我读到了有关图形、关联对象、轴、其他对象的内容......我很困惑),但我也在自学它以备考试和我并不是一个真正的技术人员,所以也许这就是我遇到这么多麻烦的原因;从根本上来说,如果你回答并且能再花两分钟更详细地描述你在做什么,你会让我非常高兴。非常感谢您的帮助。
首先,您必须设置表面的数学域,该数学域对于每个动画帧都是恒定的,因此您可以在开始时执行此操作:
x = np.arange(0,10,0.1)
y = np.arange(0,10,0.1)
X,Y = np.meshgrid(x,y)
Run Code Online (Sandbox Code Playgroud)
然后你可以初始化该图:
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
Run Code Online (Sandbox Code Playgroud)
动画部分来了,您必须定义一个函数来描述一个动画帧和下一帧之间的变化。首先,您必须从图中清除上一帧中已经绘制的内容,以便您可以使用ax.cla()
.
然后是数学部分:您必须定义函数以及它如何随时间变化。请注意,该animate
函数需要一个参数,n
在您的情况下,该参数在每帧中增加1
,您可以使用它来描述连续帧之间的变化。例如,如果我写u = np.sin((X + Y) + n)
,则滑道表面将在每次迭代中增加其相位,因此它将“向前移动”;您可以重新定义该方程,以便通过正确使用该n
参数来实现您的目标。
然后是时候用 绘制曲面了ax.plot_surface(X, Y, u)
。这不是强制性的,但我建议修复轴限制,以改进动画,使用ax.set_zlim(-2, 2)
.
这样animate
函数就定义为:
def animate(n):
ax.cla()
u = np.sin((X + Y) + n)
ax.plot_surface(X, Y, u)
ax.set_zlim(-2, 2)
return fig,
Run Code Online (Sandbox Code Playgroud)
FuncAnimation
最后,您必须使用所需的参数设置对象:
anim = FuncAnimation(fig = fig, func = animate, frames = 10, interval = 1, repeat = False)
Run Code Online (Sandbox Code Playgroud)
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
x = np.arange(0,10,0.1)
y = np.arange(0,10,0.1)
X,Y = np.meshgrid(x,y)
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
def animate(n):
ax.cla()
u = np.sin((X + Y) + n)
ax.plot_surface(X, Y, u)
ax.set_zlim(-2, 2)
return fig,
anim = FuncAnimation(fig = fig, func = animate, frames = 10, interval = 1, repeat = False)
anim.save('A.mp4',fps=10)
Run Code Online (Sandbox Code Playgroud)
另一个更改表面公式的示例,如果您使用:
u = np.sin(5/2/np.pi*n)*np.sin((X + Y))
Run Code Online (Sandbox Code Playgroud)
在函数内animate
,则表面相位将保持恒定,但滑曲线表面振幅将发生变化,遵循滑曲线函数本身,因此您将得到:
这是另一个例子。我从 JavaScript 库vis3d的图库中借用了它,并感谢 @Zephyr 的回答,将其转换为 Python。
from math import pi, cos, sin
import numpy as np
import matplotlib.colors as mcolors
from matplotlib import cm
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
x_ = np.linspace(0, 314, 50)
y_ = np.linspace(0, 314, 50)
X, Y = np.meshgrid(x_, y_)
t_ = np.linspace(0, 2*pi, 90)
def f(x, y):
return np.sin(x/50) * np.cos(y/50) * 50 + 50
def g(x, y, t):
return f(x*cos(t) - y*sin(t), x*sin(t) + y*cos(t))
fig = plt.figure()
ax = fig.add_subplot(projection = "3d")
def animate(n):
ax.cla()
Z = g(X, Y, t_[n])
colorfunction = (X**2+Y**2+Z**2)
norm = mcolors.Normalize(colorfunction.min(), colorfunction.max())
ax.plot_surface(
X, Y, Z, rstride = 1, cstride = 1, facecolors=cm.jet(norm(colorfunction))
)
ax.set_zlim(0, 100)
return fig
anim = FuncAnimation(
fig = fig, func = animate, frames = len(t_), interval = 1, repeat = False
)
anim.save("Anim.mp4", fps = 10)
Run Code Online (Sandbox Code Playgroud)
(感谢网站ezgif.com,我将 mp4 转换为 gif ,但 gif 太大了,所以我用gifsicle压缩它,但质量有所损失。)
更好的动图:
归档时间: |
|
查看次数: |
1853 次 |
最近记录: |