Exercises — Animation — FuncAnimation
5.4.18 · D4· Coding › Scientific Computing (Python) › Animation — FuncAnimation
Yeh page Animation — FuncAnimation ke liye ek graded ladder of problems hai. Har problem cleanly batata hai kya karna hai; full solution ek collapsible callout ke andar hidden hai taaki tum pehle khud try kar sako. Upar se neeche karo — levels ek dusre pe build karte hain.
Prerequisites jinhe tum use kar sakte ho: Matplotlib Figure and Axes, Artists in Matplotlib, Generators in Python, Event Loops / GUI backends, NumPy linspace and broadcasting, Saving figures and ffmpeg.
Level 1 — Recognition
L1·Q1 — Har frame pe kya call hota hai?
FuncAnimation(fig, update, frames=200, interval=20, blit=True) mein, woh function batao jo har frame pe ek baar run hota hai, aur bolo ki ek pass mein kitni baar run hota hai.
Recall Solution
update function update har frame pe ek baar run hota hai. frames=200 ke saath yeh ek pass mein 200 baar run hota hai (frames numbered 0 to 199).
Kyun: FuncAnimation timer ka malik hai; har timer tick = ek update(frame) call = ek redraw.
L1·Q2 — interval → FPS
interval=40 ms ko frames per second mein convert karo.
Recall Solution
Division kyun: har frame interval milliseconds cost karta hai, aur ek second mein 1000 ms hote hain, isliye 1000/40 frames ek second mein fit hote hain.
L1·Q3 — blit return type
blit=True ke saath, init_func aur update ko kya return karna chahiye?
Recall Solution
Changed artists ka iterable, jaise return line, (ek 1-tuple).
Kyun: blitting sirf uss artists ko hi redraw karta hai jo tum return karte ho; use batana padta hai kya badla.
Level 2 — Application
L2·Q1 — Total runtime
Ek animation mein frames=150 aur interval=20 ms hai, repeat=False. Ek pass mein kitne seconds lagte hain?
Recall Solution
Kyun: time-per-frame × number-of-frames = ek pass ka total wall-clock time.
L2·Q2 — Target FPS ke liye interval choose karo
Tum exactly 30 FPS chahte ho. Kaunsa interval (ms, integer) pass karoge?
Recall Solution
FPS formula ko invert karo:
Tumhe ek integer pass karna hai, isliye interval=33 use karo. Yeh FPS deta hai — close hai, par exact nahi. (Exact 30 FPS ke liye jab saving karo, to save ko fps=30 pass karo, jo interval ko ignore karta hai.)
L2·Q3 — Canonical skeleton fill in karo
Blanks complete karo taaki ek dot ke saath move kare:
x = np.linspace(0, 2*np.pi, 100)
dot, = ax.plot([], [], 'ro')
def update(i):
dot.set_data(______, ______) # frame i selects one point
return ______Recall Solution
def update(i):
dot.set_data([x[i]], [np.sin(x[i])]) # lists, because set_data wants sequences
return dot,Brackets [x[i]] kyun: set_data dono x aur y ke liye sequences (arrays/lists) expect karta hai, chahe ek hi point ho. Bare scalar x[i] raise ya misbehave kar sakta hai.
return dot, kyun: trailing comma ek 1-tuple banata hai — woh iterable jo blit ko chahiye.
Level 3 — Analysis
L3·Q1 — Vanishing animation
Yeh run hota hai, window khulti hai, lekin kuch move nahi karta aur phir window blank ho jaati hai. Kyun? Fix karo.
def make():
fig, ax = plt.subplots()
line, = ax.plot([], [])
FuncAnimation(fig, update, frames=100, interval=30, blit=True)
plt.show()
make()Recall Solution
Cause: FuncAnimation(...) ek variable mein store nahi hai. Jab make() return karta hai, Python ke paas animation object ka koi live reference nahi hai, isliye woh garbage-collected ho jaata hai; uska timer mar jaata hai aur frames ruk jaate hain.
Fix: ek reference alive rakho:
anim = FuncAnimation(fig, update, frames=100, interval=30, blit=True)
plt.show() # anim stays alive for the whole show()Reference kyun matter karta hai: woh timer jo frames drive karta hai animation object ke andar rehta hai. Koi object nahi → koi timer nahi → koi frames nahi.
L3·Q2 — Growing memory leak
Blitting "kabhi kabhi poora plot redraw karta hai" aur memory badhti rehti hai. Diagnose karo:
def update(frame):
ax.plot(x, np.sin(x - 0.1*frame)) # draw this frame
return ax.linesRecall Solution
Cause: ax.plot har frame pe ek naya Line2D artist add karta hai. Purane lines kabhi remove nahi hote → axes mein saikadon lines accumulate ho jaate hain (memory badhti hai), aur blit nahi bata sakta kya actually "badla."
Fix: line ko ek baar update ke bahar banao, phir sirf isko mutate karo:
line, = ax.plot([], []) # created ONCE
def update(frame):
line.set_data(x, np.sin(x - 0.1*frame)) # mutate, don't add
return line,Blitting ka poora point yahi hai: cost "har artist jo kabhi bhi add hua use redraw karo" se gir ke "ek moving line ko redraw karo" ho jaati hai.
L3·Q3 — Frozen second artist
Ek moving line + ek trailing dot: line animate hoti hai, lekin dot frozen dikhta hai. Kyun?
def update(i):
line.set_data(x[:i], np.sin(x[:i]))
dot.set_data([x[i]], [np.sin(x[i])])
return line, # <-- look hereRecall Solution
Cause: blit=True ke saath, matplotlib exactly wohi redraw karta hai jo tum return karte ho. Tumne sirf line, return kiya, isliye dot kabhi re-blitted nahi hota — woh stuck lagta hai.
Fix: saare changed artists return karo:
return line, dotKyun: blit ka contract hai "main precisely is iterable ko repaint karunga." Koi artist bhool jao aur woh screen pe update nahi hoga.
Level 4 — Synthesis
L4·Q1 — Generator-driven, save-correct animation
Ek FuncAnimation likho jahan har frame ka phase ek generator se aata hai jo ko se se just under tak ke steps mein step karta hai, aur jo mp4 mein sahi save hoga. Exact save_count batao jo chahiye aur kyun.
Recall Solution
def frame_gen():
t = 0.0
while t < 6.28:
yield t
t += 0.04
def update(t):
line.set_data(x, np.sin(x - t))
return line,
anim = FuncAnimation(fig, update, frames=frame_gen,
init_func=init, interval=20, blit=True,
save_count=157)
anim.save("wave.mp4", fps=50)Kitne frames? Values count karo jo se strictly kam hain. Steps ki sankhya hai
Kyunki strictly se kam nahi hai, last emitted value step pe hai (value ), indices = 157 frames deta hai.
save_count kyun: ek generator ki unknown length hoti hai; jab saving karo, matplotlib ko pata hona chahiye kitne frames pull karne hain. save_count ise cap karta hai — ise true frame count pe set karo taaki kuch drop ya pad na ho.
L4·Q2 — On-screen speed ko saved speed se match karo
Screen pe tum interval=25 ms use karte ho. Phir tum anim.save("out.mp4", fps=?) se save karte ho. Kaunsa fps saved video ko live preview ki same speed pe play karega? Agar tum fps=50 se save karo to kya hoga?
Recall Solution
Live FPS hai. Speed match karne ke liye ==fps=40== se save karo.
Agar tum fps=50 se save karo: same number of frames ab ki jagah per second play hote hain, isliye video faster hai (chhoti duration).
Dono alag kyun ho sakte hain: interval sirf live GUI timer control karta hai; save(fps=...) same frames ko seconds each pe re-space karta hai, interval ko bilkul ignore karta hai.
Level 5 — Mastery
L5·Q1 — Duration under repeat aur save
Ek generator 90 frames yield karta hai. Live preview interval=40 ms ke saath repeat=True use karta hai. Phir tum anim.save("m.mp4", fps=30) se save karte ho.
(a) Ek live pass kitna lamba hai (seconds)?
(b) Kya repeat=True saved file ki length change karta hai? Explain karo.
(c) Saved video kitna lamba hai (seconds)?
Recall Solution
(a) Ek live pass:
(b) Nahi. repeat sirf live preview ko loop karta hai. Saving har frame ko ek baar capture karta hai (save_count tak), isliye file mein repeat ke baad bhi ek hi pass hota hai.
(c) Saved video:
(a) ≠ (c) kyun: live spacing ms/frame hai (⇒ 25 FPS effective), lekin file s/frame pe spaced hai. Same 90 frames, alag playback rate ⇒ alag duration.
L5·Q2 — Jab blit hurt karta hai, aur init contract
(a) Ek concrete situation do jahan blit=True actually kuch visible update karne mein fail karta hai chahe update moving line ke liye sahi ho.
(b) init_func exist kyun karta hai — blit use karte waqt ise omit karne se kya toot jaata hai?
Recall Solution
(a) Agar static scene ka koi hissa change hota hai (jaise tum title ya tick labels ya axis limits update ke andar update karte ho), blit use repaint nahi karega: blit background bitmap ko ek baar cache karta hai aur sirf returned artists ko re-blit karta hai. Title/ticks cached background mein hote hain, isliye woh frozen lagte hain ya smears chhodh dete hain. (Fix: blit ke under background elements animate mat karo, ya unhe bhi return karo / blit disable karo.)
(b) init_func clean "frame-before-0" state draw karta hai. Blit ke under, yeh woh frame hai jise matplotlib reusable background bitmap ke roop mein capture karta hai. Ise omit karo aur pehla cached background leftover/empty artist state include kar sakta hai, ghosting ya blank first frame cause karte hue. Yeh repeat ke liye ek well-defined starting picture bhi guarantee karta hai.
Yeh deep rule kyun hai: blit ki speed background ko freeze karne se aati hai. Jo kuch bhi tum move karna chahte ho use (i) returned artist hona chahiye aur (ii) us frozen background ke upar rehna chahiye.
L5·Q3 — linspace indexing se exact frame count
Ek trail x = np.linspace(0, 1, 51) use karta hai aur update(i) x[:i] plot karta hai. frames=range(0, 51). Last frame pe trail mein kitne points hain, aur drawn sabse bada x-value kya hai?
Recall Solution
Last frame i = 50 hai (kyunki range(0,51) = 0..50). Phir x[:50] indices 0..49 leta hai → 50 points, sabse bada x = x[49].
51 points pe evenly: spacing , isliye
kyun nahi: x[:i] with i=50 ek half-open slice hai — yeh index 50 ko exclude karta hai. Final point kabhi appear nahi hota jab tak tum i=51 allow nahi karte (ya x[:i+1] slice nahi karte).
Recall wrap-up
Connections
- Animation — FuncAnimation — woh parent topic jise yeh drill karta hai.
- Artists in Matplotlib —
set_data, kyun ek artist ek baar create hota hai. - Generators in Python — L4/L5 mein
frame_gen. - Event Loops / GUI backends — kyun reference/timer alive rehna chahiye.
- NumPy linspace and broadcasting — L5·Q3 mein
linspaceindexing. - Saving figures and ffmpeg —
save(fps=...)vs liveinterval. - Matplotlib Figure and Axes — woh persistent canvas jo update hota rehta hai.