我是 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(第一個重復):

我已經嘗試了很多來弄清楚發生了什么,但無法理解,奇怪的是,我print在animate函式內部的陳述句為兩個不同的串列列印了 11 點和 10 點,但它們都錯過了影片和檔案中的一幀. 任何線索?
uj5u.com熱心網友回復:
在我看來,您的問題來自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()
輸出給出:

uj5u.com熱心網友回復:
撥弄好一點點與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 分:

也能夠洗掉framesarg 但只是為了可視化而不是保存我的影片,請參閱:
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.
......
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/375378.html
標籤:Python 蟒蛇-3.x matplotlib 动画片 matplotlib-动画
