Matplotlib animation.FuncAnimation() 动画错过第一帧?
Matplotlib animation.FuncAnimation() animation miss first frame?
我是 Python 和 Matplotlib 的新手。我有这段代码可以在 3d Matplotlib 子图中绘制轨迹:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from itertools import islice
import sympy as sym
from sympy.parsing.sympy_parser import parse_expr
from sympy import Eq, solve
class FunZ:
def __init__(self, f):
self.x, self.y = sym.symbols('x y')
self.f = parse_expr(f)
# print('f : ', self.f)
def evalu(self, xx, yy):
return float(self.f.subs({self.x: xx, self.y: yy}).evalf())
def derX(self, xx, yy):
self.dx = sym.diff(self.f, self.x)
# print('dx : ', self.dx)
return float(self.dx.subs({self.x: xx, self.y: yy}).evalf())
def derY(self, xx, yy):
self.dy = sym.diff(self.f, self.y)
# print('dy :', self.dy)
return float(self.dy.subs({self.x: xx, self.y: yy}).evalf())
def derXY(self, xx, yy):
return [float(self.derX(xx, yy)), float(self.derY(xx, yy))]
def minim(self):
self.dx = sym.diff(self.f, self.x)
self.dy = sym.diff(self.f, self.y)
print('dx : ', self.dx)
print('dy : ', self.dy)
eq1 = Eq(self.dx ,0)
eq2 = Eq(self.dy ,0)
solu = solve((eq1,eq2), (self.x, self.y), dict= False)
print(solu, type(solu))
return solu
XX = np.linspace(-4, 4, 100)
YY = np.linspace(-4, 4, 100)
funz = FunZ('x**2 + y**2 + 2*y + 2')
ij = [(x, y, funz.evalu(x, y)) for x in XX for y in YY]
arr = np.array(ij, dtype=float)
# print(arr, arr.size, arr.shape, arr.dtype)
der_x = [(a, b, funz.derX(a, b)) for a in XX for b in YY]
derX = np.array(der_x)
# print(derX, derX.size, derX.shape, derX.dtype)
der_y = [(a, b, funz.derY(a, b)) for a in XX for b in YY]
derY = np.array(der_y)
# print(derY, derY.size, derY.shape, derY.dtype)
x = arr[:, 0]
y = arr[:, 1]
data = arr[:, 2]
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.set_xlim([-4,4])
ax.set_ylim([-4,4])
ax.set_zlim([-3,50])
ax.plot_trisurf(x, y, data, color="red", alpha=0.5)
### devo duplicare primo elemento della lista altrimenti skippa a visualizzare i primi due sul video
# trajectory = [(2.5, 3.5, 27.5),(2.5, 3.5, 27.5), (2.0, 3.0, 21.0), (1.5, 2.5, 15.5), (1.0, 2.0, 11.0), (0.5, 1.5, 7.5), (0.0, 1.0, 5.0), (0.0, 0.5, 3.25), (0.0, 0.0, 2.0), (0.0, -0.5, 1.25), (0.0, -1.0, 1.0)]
trajectory = [(2.5, 3.5, 27.5), (2.0, 3.0, 21.0), (1.5, 2.5, 15.5), (1.0, 2.0, 11.0), (0.5, 1.5, 7.5), (0.0, 1.0, 5.0), (0.0, 0.5, 3.25), (0.0, 0.0, 2.0), (0.0, -0.5, 1.25), (0.0, -1.0, 1.0)]
print('len trajectory : ', len(trajectory))
i = islice(trajectory, 0 , len(trajectory), 1)
pippo = None
def animate(j): #funziona senza stop iteration with animation.save
global pippo
try:
coord = next(i)
except:
print('coord empty')
return
if pippo:
pippo.remove()
print(coord)
x = coord[0]
y = coord[1]
z = coord[2]
pippo = ax.scatter(x,y,z)
return pippo
ani = animation.FuncAnimation(fig, animate, interval=1000, frames=len(trajectory), repeat=False) # e' necessario
plt.show()
plt.close('all')
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.set_xlim([-4,4])
ax.set_ylim([-4,4])
ax.set_zlim([-3,50])
ax.plot_trisurf(x, y, data, color="red", alpha=0.5)
print('#####################')
i = islice(trajectory, 0 , len(trajectory), 1)
ani2 = animation.FuncAnimation(fig, animate, interval=1000, frames=len(trajectory), repeat=False)
# writervideo = animation.FFMpegWriter(fps=1, codec="h264")
# ani2.save('video_steeper.mp4', writer=writervideo)
ani2.save("movie.gif", writer=animation.PillowWriter(fps=1))
我正在努力理解为什么要制作正确的动画并保存动画我需要复制 trajectory
列表的第一个元素 ((2.5, 3.5, 27.5))。
如果我不这样做,动画和我的 gif 只显示 9 个点而不是 10 个点,请查看结果输出:
来自 10 个元素列表的电影 trajectory
:
来自 11 个元素列表的电影 trajectory
(第一个重复):
我已经尝试了很多来弄清楚发生了什么但无法理解,奇怪的是我在 animate
函数中的 print
语句准确地打印了 11 和 10 点两个不同的列表,但它们都错过了动画和文件中的帧。有什么线索吗?
在我看来,您的问题来自您正在创建的可迭代 i
和函数 next
的使用。我不确定为什么会发生这种情况,但是如果您不创建可迭代对象 i
而只是直接索引您的轨迹,那么您的动画会按预期工作。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from itertools import islice
import sympy as sym
from sympy.parsing.sympy_parser import parse_expr
from sympy import Eq, solve
class FunZ:
def __init__(self, f):
self.x, self.y = sym.symbols('x y')
self.f = parse_expr(f)
def evalu(self, xx, yy):
return float(self.f.subs({self.x: xx, self.y: yy}).evalf())
def derX(self, xx, yy):
self.dx = sym.diff(self.f, self.x)
return float(self.dx.subs({self.x: xx, self.y: yy}).evalf())
def derY(self, xx, yy):
self.dy = sym.diff(self.f, self.y)
return float(self.dy.subs({self.x: xx, self.y: yy}).evalf())
def derXY(self, xx, yy):
return [float(self.derX(xx, yy)), float(self.derY(xx, yy))]
def minim(self):
self.dx = sym.diff(self.f, self.x)
self.dy = sym.diff(self.f, self.y)
print('dx : ', self.dx)
print('dy : ', self.dy)
eq1 = Eq(self.dx ,0)
eq2 = Eq(self.dy ,0)
solu = solve((eq1,eq2), (self.x, self.y), dict= False)
print(solu, type(solu))
return solu
XX = np.linspace(-4, 4, 100)
YY = np.linspace(-4, 4, 100)
funz = FunZ('x**2 + y**2 + 2*y + 2')
ij = [(x, y, funz.evalu(x, y)) for x in XX for y in YY]
arr = np.array(ij, dtype=float)
der_x = [(a, b, funz.derX(a, b)) for a in XX for b in YY]
derX = np.array(der_x)
der_y = [(a, b, funz.derY(a, b)) for a in XX for b in YY]
derY = np.array(der_y)
x = arr[:, 0]
y = arr[:, 1]
data = arr[:, 2]
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.set_xlim([-4,4])
ax.set_ylim([-4,4])
ax.set_zlim([-3,50])
ax.plot_trisurf(x, y, data, color="red", alpha=0.5)
trajectory = [(2.5, 3.5, 27.5), (2.0, 3.0, 21.0), (1.5, 2.5, 15.5), (1.0, 2.0, 11.0), (0.5, 1.5, 7.5), (0.0, 1.0, 5.0), (0.0, 0.5, 3.25), (0.0, 0.0, 2.0), (0.0, -0.5, 1.25), (0.0, -1.0, 1.0)]
print('len trajectory : ', len(trajectory))
pippo = None
def animate(j): #funziona senza stop iteration with animation.save
global pippo
x = trajectory[j][0]
y = trajectory[j][1]
z = trajectory[j][2]
if pippo is not None:
pippo.remove()
pippo = ax.scatter(x,y,z)
return pippo
ani = animation.FuncAnimation(fig, animate, interval=1000, frames=len(trajectory), repeat=False) # e' necessario
plt.show()
输出给出:
很好地摆弄了一下 FuncAnimation
添加一个 init_func
:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from itertools import islice
import sympy as sym
from sympy.parsing.sympy_parser import parse_expr
from sympy import Eq, solve
class FunZ:
def __init__(self, f):
self.x, self.y = sym.symbols('x y')
self.f = parse_expr(f)
# print('f : ', self.f)
def evalu(self, xx, yy):
return float(self.f.subs({self.x: xx, self.y: yy}).evalf())
def derX(self, xx, yy):
self.dx = sym.diff(self.f, self.x)
# print('dx : ', self.dx)
return float(self.dx.subs({self.x: xx, self.y: yy}).evalf())
def derY(self, xx, yy):
self.dy = sym.diff(self.f, self.y)
# print('dy :', self.dy)
return float(self.dy.subs({self.x: xx, self.y: yy}).evalf())
def derXY(self, xx, yy):
return [float(self.derX(xx, yy)), float(self.derY(xx, yy))]
def minim(self):
self.dx = sym.diff(self.f, self.x)
self.dy = sym.diff(self.f, self.y)
print('dx : ', self.dx)
print('dy : ', self.dy)
eq1 = Eq(self.dx ,0)
eq2 = Eq(self.dy ,0)
solu = solve((eq1,eq2), (self.x, self.y), dict= False)
print(solu, type(solu))
return solu
XX = np.linspace(-4, 4, 100)
YY = np.linspace(-4, 4, 100)
funz = FunZ('x**2 + y**2 + 2*y + 2')
ij = [(x, y, funz.evalu(x, y)) for x in XX for y in YY]
arr = np.array(ij, dtype=float)
# print(arr, arr.size, arr.shape, arr.dtype)
der_x = [(a, b, funz.derX(a, b)) for a in XX for b in YY]
derX = np.array(der_x)
# print(derX, derX.size, derX.shape, derX.dtype)
der_y = [(a, b, funz.derY(a, b)) for a in XX for b in YY]
derY = np.array(der_y)
# print(derY, derY.size, derY.shape, derY.dtype)
x = arr[:, 0]
y = arr[:, 1]
data = arr[:, 2]
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.set_xlim([-4,4])
ax.set_ylim([-4,4])
ax.set_zlim([-3,50])
ax.plot_trisurf(x, y, data, color="red", alpha=0.5)
trajectory = [(2.5, 3.5, 27.5), (2.0, 3.0, 21.0), (1.5, 2.5, 15.5), (1.0, 2.0, 11.0), (0.5, 1.5, 7.5), (0.0, 1.0, 5.0), (0.0, 0.5, 3.25), (0.0, 0.0, 2.0), (0.0, -0.5, 1.25), (0.0, -1.0, 1.0)]
print('len trajectory : ', len(trajectory))
i = islice(trajectory, 0 , len(trajectory), 1)
def init_animate():
ax.plot_trisurf(x, y, data, color="green", alpha=0.5)
pippo = None
def animate(j): #funziona senza stop iteration with animation.save
global pippo
try:
coord = next(i)
except:
print('coord empty')
return
if pippo:
pippo.remove()
print(coord)
x = coord[0]
y = coord[1]
z = coord[2]
pippo = ax.scatter(x,y,z)
return pippo
ani = animation.FuncAnimation(fig, animate, interval=1000, frames=len(trajectory),init_func=init_animate, repeat=False)
plt.show()
plt.close('all')
print('#####################')
能够在 gif 上获得所有 10 分:
也能够删除 frames
arg 但只是为了可视化而不是保存我的动画,请参阅:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from itertools import islice
import sympy as sym
from sympy.parsing.sympy_parser import parse_expr
from sympy import Eq, solve
class FunZ:
def __init__(self, f):
self.x, self.y = sym.symbols('x y')
self.f = parse_expr(f)
# print('f : ', self.f)
def evalu(self, xx, yy):
return float(self.f.subs({self.x: xx, self.y: yy}).evalf())
def derX(self, xx, yy):
self.dx = sym.diff(self.f, self.x)
# print('dx : ', self.dx)
return float(self.dx.subs({self.x: xx, self.y: yy}).evalf())
def derY(self, xx, yy):
self.dy = sym.diff(self.f, self.y)
# print('dy :', self.dy)
return float(self.dy.subs({self.x: xx, self.y: yy}).evalf())
def derXY(self, xx, yy):
return [float(self.derX(xx, yy)), float(self.derY(xx, yy))]
def minim(self):
self.dx = sym.diff(self.f, self.x)
self.dy = sym.diff(self.f, self.y)
print('dx : ', self.dx)
print('dy : ', self.dy)
eq1 = Eq(self.dx ,0)
eq2 = Eq(self.dy ,0)
solu = solve((eq1,eq2), (self.x, self.y), dict= False)
print(solu, type(solu))
return solu
XX = np.linspace(-4, 4, 100)
YY = np.linspace(-4, 4, 100)
funz = FunZ('x**2 + y**2 + 2*y + 2')
ij = [(x, y, funz.evalu(x, y)) for x in XX for y in YY]
arr = np.array(ij, dtype=float)
# print(arr, arr.size, arr.shape, arr.dtype)
der_x = [(a, b, funz.derX(a, b)) for a in XX for b in YY]
derX = np.array(der_x)
# print(derX, derX.size, derX.shape, derX.dtype)
der_y = [(a, b, funz.derY(a, b)) for a in XX for b in YY]
derY = np.array(der_y)
# print(derY, derY.size, derY.shape, derY.dtype)
x = arr[:, 0]
y = arr[:, 1]
data = arr[:, 2]
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.set_xlim([-4,4])
ax.set_ylim([-4,4])
ax.set_zlim([-3,50])
ax.plot_trisurf(x, y, data, color="red", alpha=0.5)
### devo duplicare primo elemento della lista altrimenti skippa a visualizzare i primi due sul video
trajectory = [(2.5, 3.5, 27.5), (2.0, 3.0, 21.0), (1.5, 2.5, 15.5), (1.0, 2.0, 11.0), (0.5, 1.5, 7.5), (0.0, 1.0, 5.0), (0.0, 0.5, 3.25), (0.0, 0.0, 2.0), (0.0, -0.5, 1.25), (0.0, -1.0, 1.0)]
# trajectory = [(2.5, 3.5, 27.5), (2.0, 3.0, 21.0), (1.5, 2.5, 15.5), (1.0, 2.0, 11.0), (0.5, 1.5, 7.5), (0.0, 1.0, 5.0), (0.0, 0.5, 3.25), (0.0, 0.0, 2.0), (0.0, -0.5, 1.25), (0.0, -1.0, 1.0)]
print('len trajectory : ', len(trajectory))
i = islice(trajectory, 0 , len(trajectory), 1)
def init_animate():
ax.plot_trisurf(x, y, data, color="blue", alpha=0.5)
pippo = None
def animate(j): #funziona senza stop iteration with animation.save
global pippo
try:
coord = next(i)
print(coord)
except:
print('coord empty')
global ani
global ani2
ani = None
ani2 = None
return
if pippo:
pippo.remove()
# print(coord)
x = coord[0]
y = coord[1]
z = coord[2]
pippo = ax.scatter(x,y,z)
return pippo
# ani = animation.FuncAnimation(fig, animate ,frames=len(trajectory),init_func=init_animate, interval=1000, repeat=False)
ani = animation.FuncAnimation(fig, animate, init_func=init_animate, interval=1000, repeat=False)
plt.show()
print('test to see if everything is fine')
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.set_xlim([-4,4])
ax.set_ylim([-4,4])
ax.set_zlim([-3,50])
ax.plot_trisurf(x, y, data, color="red", alpha=0.5)
print('#####################')
i = islice(trajectory, 0 , len(trajectory), 1)
ani2 = animation.FuncAnimation(fig, animate, init_func=init_animate, interval=1000, repeat=False).save("movie_init_no-frames.gif", writer=animation.PillowWriter(fps=1))
不知道发生了什么,但算法保持 运行,输出:
len trajectory : 10
(2.5, 3.5, 27.5)
(2.0, 3.0, 21.0)
(1.5, 2.5, 15.5)
(1.0, 2.0, 11.0)
(0.5, 1.5, 7.5)
(0.0, 1.0, 5.0)
(0.0, 0.5, 3.25)
(0.0, 0.0, 2.0)
(0.0, -0.5, 1.25)
(0.0, -1.0, 1.0)
coord empty
test to see if everything is fine
#####################
(2.5, 3.5, 27.5)
(2.0, 3.0, 21.0)
(1.5, 2.5, 15.5)
(1.0, 2.0, 11.0)
(0.5, 1.5, 7.5)
(0.0, 1.0, 5.0)
(0.0, 0.5, 3.25)
(0.0, 0.0, 2.0)
(0.0, -0.5, 1.25)
(0.0, -1.0, 1.0)
coord empty
coord empty
coord empty
^Z
[9]+ Stopped
我想这与 FuncAnimation
的内部有关。
尽管如此,我还是应该花时间尝试理解 j
文档
根据 help(matplotlib.animation)
......
class FuncAnimation(TimedAnimation)
| FuncAnimation(fig, func, frames=None, init_func=None, fargs=None, save_count=None, *, cache_frame_data=True, **kwargs)
|
| Makes an animation by repeatedly calling a function *func*.
|
| Parameters
| ----------
| fig : `~matplotlib.figure.Figure`
| The figure object used to get needed events, such as draw or resize.
|
| func : callable
| The function to call at each frame. The first argument will
| be the next value in *frames*. Any additional positional
| arguments can be supplied via the *fargs* parameter.
|
| The required signature is::
|
| def func(frame, *fargs) -> iterable_of_artists
|
| If ``blit == True``, *func* must return an iterable of all artists
| that were modified or created. This information is used by the blitting
| algorithm to determine which parts of the figure have to be updated.
| The return value is unused if ``blit == False`` and may be omitted in
| that case.
......
我是 Python 和 Matplotlib 的新手。我有这段代码可以在 3d Matplotlib 子图中绘制轨迹:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from itertools import islice
import sympy as sym
from sympy.parsing.sympy_parser import parse_expr
from sympy import Eq, solve
class FunZ:
def __init__(self, f):
self.x, self.y = sym.symbols('x y')
self.f = parse_expr(f)
# print('f : ', self.f)
def evalu(self, xx, yy):
return float(self.f.subs({self.x: xx, self.y: yy}).evalf())
def derX(self, xx, yy):
self.dx = sym.diff(self.f, self.x)
# print('dx : ', self.dx)
return float(self.dx.subs({self.x: xx, self.y: yy}).evalf())
def derY(self, xx, yy):
self.dy = sym.diff(self.f, self.y)
# print('dy :', self.dy)
return float(self.dy.subs({self.x: xx, self.y: yy}).evalf())
def derXY(self, xx, yy):
return [float(self.derX(xx, yy)), float(self.derY(xx, yy))]
def minim(self):
self.dx = sym.diff(self.f, self.x)
self.dy = sym.diff(self.f, self.y)
print('dx : ', self.dx)
print('dy : ', self.dy)
eq1 = Eq(self.dx ,0)
eq2 = Eq(self.dy ,0)
solu = solve((eq1,eq2), (self.x, self.y), dict= False)
print(solu, type(solu))
return solu
XX = np.linspace(-4, 4, 100)
YY = np.linspace(-4, 4, 100)
funz = FunZ('x**2 + y**2 + 2*y + 2')
ij = [(x, y, funz.evalu(x, y)) for x in XX for y in YY]
arr = np.array(ij, dtype=float)
# print(arr, arr.size, arr.shape, arr.dtype)
der_x = [(a, b, funz.derX(a, b)) for a in XX for b in YY]
derX = np.array(der_x)
# print(derX, derX.size, derX.shape, derX.dtype)
der_y = [(a, b, funz.derY(a, b)) for a in XX for b in YY]
derY = np.array(der_y)
# print(derY, derY.size, derY.shape, derY.dtype)
x = arr[:, 0]
y = arr[:, 1]
data = arr[:, 2]
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.set_xlim([-4,4])
ax.set_ylim([-4,4])
ax.set_zlim([-3,50])
ax.plot_trisurf(x, y, data, color="red", alpha=0.5)
### devo duplicare primo elemento della lista altrimenti skippa a visualizzare i primi due sul video
# trajectory = [(2.5, 3.5, 27.5),(2.5, 3.5, 27.5), (2.0, 3.0, 21.0), (1.5, 2.5, 15.5), (1.0, 2.0, 11.0), (0.5, 1.5, 7.5), (0.0, 1.0, 5.0), (0.0, 0.5, 3.25), (0.0, 0.0, 2.0), (0.0, -0.5, 1.25), (0.0, -1.0, 1.0)]
trajectory = [(2.5, 3.5, 27.5), (2.0, 3.0, 21.0), (1.5, 2.5, 15.5), (1.0, 2.0, 11.0), (0.5, 1.5, 7.5), (0.0, 1.0, 5.0), (0.0, 0.5, 3.25), (0.0, 0.0, 2.0), (0.0, -0.5, 1.25), (0.0, -1.0, 1.0)]
print('len trajectory : ', len(trajectory))
i = islice(trajectory, 0 , len(trajectory), 1)
pippo = None
def animate(j): #funziona senza stop iteration with animation.save
global pippo
try:
coord = next(i)
except:
print('coord empty')
return
if pippo:
pippo.remove()
print(coord)
x = coord[0]
y = coord[1]
z = coord[2]
pippo = ax.scatter(x,y,z)
return pippo
ani = animation.FuncAnimation(fig, animate, interval=1000, frames=len(trajectory), repeat=False) # e' necessario
plt.show()
plt.close('all')
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.set_xlim([-4,4])
ax.set_ylim([-4,4])
ax.set_zlim([-3,50])
ax.plot_trisurf(x, y, data, color="red", alpha=0.5)
print('#####################')
i = islice(trajectory, 0 , len(trajectory), 1)
ani2 = animation.FuncAnimation(fig, animate, interval=1000, frames=len(trajectory), repeat=False)
# writervideo = animation.FFMpegWriter(fps=1, codec="h264")
# ani2.save('video_steeper.mp4', writer=writervideo)
ani2.save("movie.gif", writer=animation.PillowWriter(fps=1))
我正在努力理解为什么要制作正确的动画并保存动画我需要复制 trajectory
列表的第一个元素 ((2.5, 3.5, 27.5))。
如果我不这样做,动画和我的 gif 只显示 9 个点而不是 10 个点,请查看结果输出:
来自 10 个元素列表的电影 trajectory
:
来自 11 个元素列表的电影 trajectory
(第一个重复):
我已经尝试了很多来弄清楚发生了什么但无法理解,奇怪的是我在 animate
函数中的 print
语句准确地打印了 11 和 10 点两个不同的列表,但它们都错过了动画和文件中的帧。有什么线索吗?
在我看来,您的问题来自您正在创建的可迭代 i
和函数 next
的使用。我不确定为什么会发生这种情况,但是如果您不创建可迭代对象 i
而只是直接索引您的轨迹,那么您的动画会按预期工作。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from itertools import islice
import sympy as sym
from sympy.parsing.sympy_parser import parse_expr
from sympy import Eq, solve
class FunZ:
def __init__(self, f):
self.x, self.y = sym.symbols('x y')
self.f = parse_expr(f)
def evalu(self, xx, yy):
return float(self.f.subs({self.x: xx, self.y: yy}).evalf())
def derX(self, xx, yy):
self.dx = sym.diff(self.f, self.x)
return float(self.dx.subs({self.x: xx, self.y: yy}).evalf())
def derY(self, xx, yy):
self.dy = sym.diff(self.f, self.y)
return float(self.dy.subs({self.x: xx, self.y: yy}).evalf())
def derXY(self, xx, yy):
return [float(self.derX(xx, yy)), float(self.derY(xx, yy))]
def minim(self):
self.dx = sym.diff(self.f, self.x)
self.dy = sym.diff(self.f, self.y)
print('dx : ', self.dx)
print('dy : ', self.dy)
eq1 = Eq(self.dx ,0)
eq2 = Eq(self.dy ,0)
solu = solve((eq1,eq2), (self.x, self.y), dict= False)
print(solu, type(solu))
return solu
XX = np.linspace(-4, 4, 100)
YY = np.linspace(-4, 4, 100)
funz = FunZ('x**2 + y**2 + 2*y + 2')
ij = [(x, y, funz.evalu(x, y)) for x in XX for y in YY]
arr = np.array(ij, dtype=float)
der_x = [(a, b, funz.derX(a, b)) for a in XX for b in YY]
derX = np.array(der_x)
der_y = [(a, b, funz.derY(a, b)) for a in XX for b in YY]
derY = np.array(der_y)
x = arr[:, 0]
y = arr[:, 1]
data = arr[:, 2]
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.set_xlim([-4,4])
ax.set_ylim([-4,4])
ax.set_zlim([-3,50])
ax.plot_trisurf(x, y, data, color="red", alpha=0.5)
trajectory = [(2.5, 3.5, 27.5), (2.0, 3.0, 21.0), (1.5, 2.5, 15.5), (1.0, 2.0, 11.0), (0.5, 1.5, 7.5), (0.0, 1.0, 5.0), (0.0, 0.5, 3.25), (0.0, 0.0, 2.0), (0.0, -0.5, 1.25), (0.0, -1.0, 1.0)]
print('len trajectory : ', len(trajectory))
pippo = None
def animate(j): #funziona senza stop iteration with animation.save
global pippo
x = trajectory[j][0]
y = trajectory[j][1]
z = trajectory[j][2]
if pippo is not None:
pippo.remove()
pippo = ax.scatter(x,y,z)
return pippo
ani = animation.FuncAnimation(fig, animate, interval=1000, frames=len(trajectory), repeat=False) # e' necessario
plt.show()
输出给出:
很好地摆弄了一下 FuncAnimation
添加一个 init_func
:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from itertools import islice
import sympy as sym
from sympy.parsing.sympy_parser import parse_expr
from sympy import Eq, solve
class FunZ:
def __init__(self, f):
self.x, self.y = sym.symbols('x y')
self.f = parse_expr(f)
# print('f : ', self.f)
def evalu(self, xx, yy):
return float(self.f.subs({self.x: xx, self.y: yy}).evalf())
def derX(self, xx, yy):
self.dx = sym.diff(self.f, self.x)
# print('dx : ', self.dx)
return float(self.dx.subs({self.x: xx, self.y: yy}).evalf())
def derY(self, xx, yy):
self.dy = sym.diff(self.f, self.y)
# print('dy :', self.dy)
return float(self.dy.subs({self.x: xx, self.y: yy}).evalf())
def derXY(self, xx, yy):
return [float(self.derX(xx, yy)), float(self.derY(xx, yy))]
def minim(self):
self.dx = sym.diff(self.f, self.x)
self.dy = sym.diff(self.f, self.y)
print('dx : ', self.dx)
print('dy : ', self.dy)
eq1 = Eq(self.dx ,0)
eq2 = Eq(self.dy ,0)
solu = solve((eq1,eq2), (self.x, self.y), dict= False)
print(solu, type(solu))
return solu
XX = np.linspace(-4, 4, 100)
YY = np.linspace(-4, 4, 100)
funz = FunZ('x**2 + y**2 + 2*y + 2')
ij = [(x, y, funz.evalu(x, y)) for x in XX for y in YY]
arr = np.array(ij, dtype=float)
# print(arr, arr.size, arr.shape, arr.dtype)
der_x = [(a, b, funz.derX(a, b)) for a in XX for b in YY]
derX = np.array(der_x)
# print(derX, derX.size, derX.shape, derX.dtype)
der_y = [(a, b, funz.derY(a, b)) for a in XX for b in YY]
derY = np.array(der_y)
# print(derY, derY.size, derY.shape, derY.dtype)
x = arr[:, 0]
y = arr[:, 1]
data = arr[:, 2]
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.set_xlim([-4,4])
ax.set_ylim([-4,4])
ax.set_zlim([-3,50])
ax.plot_trisurf(x, y, data, color="red", alpha=0.5)
trajectory = [(2.5, 3.5, 27.5), (2.0, 3.0, 21.0), (1.5, 2.5, 15.5), (1.0, 2.0, 11.0), (0.5, 1.5, 7.5), (0.0, 1.0, 5.0), (0.0, 0.5, 3.25), (0.0, 0.0, 2.0), (0.0, -0.5, 1.25), (0.0, -1.0, 1.0)]
print('len trajectory : ', len(trajectory))
i = islice(trajectory, 0 , len(trajectory), 1)
def init_animate():
ax.plot_trisurf(x, y, data, color="green", alpha=0.5)
pippo = None
def animate(j): #funziona senza stop iteration with animation.save
global pippo
try:
coord = next(i)
except:
print('coord empty')
return
if pippo:
pippo.remove()
print(coord)
x = coord[0]
y = coord[1]
z = coord[2]
pippo = ax.scatter(x,y,z)
return pippo
ani = animation.FuncAnimation(fig, animate, interval=1000, frames=len(trajectory),init_func=init_animate, repeat=False)
plt.show()
plt.close('all')
print('#####################')
能够在 gif 上获得所有 10 分:
也能够删除 frames
arg 但只是为了可视化而不是保存我的动画,请参阅:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from itertools import islice
import sympy as sym
from sympy.parsing.sympy_parser import parse_expr
from sympy import Eq, solve
class FunZ:
def __init__(self, f):
self.x, self.y = sym.symbols('x y')
self.f = parse_expr(f)
# print('f : ', self.f)
def evalu(self, xx, yy):
return float(self.f.subs({self.x: xx, self.y: yy}).evalf())
def derX(self, xx, yy):
self.dx = sym.diff(self.f, self.x)
# print('dx : ', self.dx)
return float(self.dx.subs({self.x: xx, self.y: yy}).evalf())
def derY(self, xx, yy):
self.dy = sym.diff(self.f, self.y)
# print('dy :', self.dy)
return float(self.dy.subs({self.x: xx, self.y: yy}).evalf())
def derXY(self, xx, yy):
return [float(self.derX(xx, yy)), float(self.derY(xx, yy))]
def minim(self):
self.dx = sym.diff(self.f, self.x)
self.dy = sym.diff(self.f, self.y)
print('dx : ', self.dx)
print('dy : ', self.dy)
eq1 = Eq(self.dx ,0)
eq2 = Eq(self.dy ,0)
solu = solve((eq1,eq2), (self.x, self.y), dict= False)
print(solu, type(solu))
return solu
XX = np.linspace(-4, 4, 100)
YY = np.linspace(-4, 4, 100)
funz = FunZ('x**2 + y**2 + 2*y + 2')
ij = [(x, y, funz.evalu(x, y)) for x in XX for y in YY]
arr = np.array(ij, dtype=float)
# print(arr, arr.size, arr.shape, arr.dtype)
der_x = [(a, b, funz.derX(a, b)) for a in XX for b in YY]
derX = np.array(der_x)
# print(derX, derX.size, derX.shape, derX.dtype)
der_y = [(a, b, funz.derY(a, b)) for a in XX for b in YY]
derY = np.array(der_y)
# print(derY, derY.size, derY.shape, derY.dtype)
x = arr[:, 0]
y = arr[:, 1]
data = arr[:, 2]
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.set_xlim([-4,4])
ax.set_ylim([-4,4])
ax.set_zlim([-3,50])
ax.plot_trisurf(x, y, data, color="red", alpha=0.5)
### devo duplicare primo elemento della lista altrimenti skippa a visualizzare i primi due sul video
trajectory = [(2.5, 3.5, 27.5), (2.0, 3.0, 21.0), (1.5, 2.5, 15.5), (1.0, 2.0, 11.0), (0.5, 1.5, 7.5), (0.0, 1.0, 5.0), (0.0, 0.5, 3.25), (0.0, 0.0, 2.0), (0.0, -0.5, 1.25), (0.0, -1.0, 1.0)]
# trajectory = [(2.5, 3.5, 27.5), (2.0, 3.0, 21.0), (1.5, 2.5, 15.5), (1.0, 2.0, 11.0), (0.5, 1.5, 7.5), (0.0, 1.0, 5.0), (0.0, 0.5, 3.25), (0.0, 0.0, 2.0), (0.0, -0.5, 1.25), (0.0, -1.0, 1.0)]
print('len trajectory : ', len(trajectory))
i = islice(trajectory, 0 , len(trajectory), 1)
def init_animate():
ax.plot_trisurf(x, y, data, color="blue", alpha=0.5)
pippo = None
def animate(j): #funziona senza stop iteration with animation.save
global pippo
try:
coord = next(i)
print(coord)
except:
print('coord empty')
global ani
global ani2
ani = None
ani2 = None
return
if pippo:
pippo.remove()
# print(coord)
x = coord[0]
y = coord[1]
z = coord[2]
pippo = ax.scatter(x,y,z)
return pippo
# ani = animation.FuncAnimation(fig, animate ,frames=len(trajectory),init_func=init_animate, interval=1000, repeat=False)
ani = animation.FuncAnimation(fig, animate, init_func=init_animate, interval=1000, repeat=False)
plt.show()
print('test to see if everything is fine')
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.set_xlim([-4,4])
ax.set_ylim([-4,4])
ax.set_zlim([-3,50])
ax.plot_trisurf(x, y, data, color="red", alpha=0.5)
print('#####################')
i = islice(trajectory, 0 , len(trajectory), 1)
ani2 = animation.FuncAnimation(fig, animate, init_func=init_animate, interval=1000, repeat=False).save("movie_init_no-frames.gif", writer=animation.PillowWriter(fps=1))
不知道发生了什么,但算法保持 运行,输出:
len trajectory : 10
(2.5, 3.5, 27.5)
(2.0, 3.0, 21.0)
(1.5, 2.5, 15.5)
(1.0, 2.0, 11.0)
(0.5, 1.5, 7.5)
(0.0, 1.0, 5.0)
(0.0, 0.5, 3.25)
(0.0, 0.0, 2.0)
(0.0, -0.5, 1.25)
(0.0, -1.0, 1.0)
coord empty
test to see if everything is fine
#####################
(2.5, 3.5, 27.5)
(2.0, 3.0, 21.0)
(1.5, 2.5, 15.5)
(1.0, 2.0, 11.0)
(0.5, 1.5, 7.5)
(0.0, 1.0, 5.0)
(0.0, 0.5, 3.25)
(0.0, 0.0, 2.0)
(0.0, -0.5, 1.25)
(0.0, -1.0, 1.0)
coord empty
coord empty
coord empty
^Z
[9]+ Stopped
我想这与 FuncAnimation
的内部有关。
尽管如此,我还是应该花时间尝试理解 j
文档
根据 help(matplotlib.animation)
......
class FuncAnimation(TimedAnimation)
| FuncAnimation(fig, func, frames=None, init_func=None, fargs=None, save_count=None, *, cache_frame_data=True, **kwargs)
|
| Makes an animation by repeatedly calling a function *func*.
|
| Parameters
| ----------
| fig : `~matplotlib.figure.Figure`
| The figure object used to get needed events, such as draw or resize.
|
| func : callable
| The function to call at each frame. The first argument will
| be the next value in *frames*. Any additional positional
| arguments can be supplied via the *fargs* parameter.
|
| The required signature is::
|
| def func(frame, *fargs) -> iterable_of_artists
|
| If ``blit == True``, *func* must return an iterable of all artists
| that were modified or created. This information is used by the blitting
| algorithm to determine which parts of the figure have to be updated.
| The return value is unused if ``blit == False`` and may be omitted in
| that case.
......