10000 transform animation can be returned as HTML5 movie, useful for Jupyter · astyl/spatialmath-python@48f164f · GitHub
[go: up one dir, main page]

Skip to content

Commit 48f164f

Browse files
committed
transform animation can be returned as HTML5 movie, useful for Jupyter
1 parent 129602f commit 48f164f

File tree

2 files changed

+33
-18
lines changed

2 files changed

+33
-18
lines changed

spatialmath/base/animate.py

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,8 @@ def run(
168168
:type nframes: int
169169
:param interval: number of milliseconds between frames [default 50]
170170
:type interval: int
171-
:param movie: name of file to write MP4 movie into
172-
:type movie: str
171+
:param movie: name of file to write MP4 movie into, or True
172+
:type movie: str, bool
173173
:param wait: wait until animation is complete, default False
174174
:type wait: bool
175175
@@ -180,6 +180,8 @@ def run(
180180
181181
- the ``movie`` option requires the ffmpeg package to be installed:
182182
``conda install -c conda-forge ffmpeg``
183+
- if ``movie=True`` then return an HTML5 video which can be displayed in a notebook
184+
using ``HTML()``
183185
- invokes the draw() method of every object in the display list
184186
"""
185187

@@ -208,9 +210,6 @@ def update(frame, animation):
208210

209211
return animation.artists()
210212

211-
global _ani
212-
213-
# blit leaves a trail and first frame
214213
if movie is not None:
215214
repeat = False
216215

@@ -223,17 +222,22 @@ def update(frame, animation):
223222
else:
224223
frames = iter(np.linspace(0, 1, nframes))
225224

225+
global _ani
226+
fig = plt.gcf()
226227
_ani = animation.FuncAnimation(
227-
fig=plt.gcf(),
228+
fig=fig,
228229
func=update,
229230
frames=frames,
230231
fargs=(self,),
231-
blit=False,
232+
blit=False, # blit leaves a trail and first frame, set to False
232233
interval=interval,
233234
repeat=repeat,
234235
)
235236

236-
if movie is not None:
237+
if movie is True:
238+
plt.close(fig)
239+
return _ani.to_html5_video()
240+
elif isinstance(movie, str):
237241
# Set up formatting for the movie files
238242
if os.path.exists(movie):
239243
print("overwriting movie", movie)
@@ -251,6 +255,8 @@ def update(frame, animation):
251255
plt.pause(0.25)
252256
if _ani.event_source is None or len(_ani.event_source.callbacks) == 0:
253257
break
258+
return _ani
259+
254260

255261
def __repr__(self):
256262
"""
@@ -570,8 +576,10 @@ def run(
570576
:type repeat: bool
571577
:param interval: number of milliseconds between frames [default 50]
572578
:type interval: int
573-
:param movie: name of file to write MP4 movie into
574-
:type movie: str
579+
:param movie: name of file to write MP4 movie into or True
580+
:type movie: str, bool
581+
:returns: Matplotlib animation object
582+
:rtype: Matplotlib animation object
575583
576584
Animates a 3D coordinate frame moving from the world frame to a frame
577585
represented by the SO(3) or SE(3) matrix to the current axes.
@@ -580,6 +588,8 @@ def run(
580588
581589
- the ``movie`` option requires the ffmpeg package to be installed:
582590
``conda install -c conda-forge ffmpeg``
591+
- if ``movie=True`` then return an HTML5 video which can be displayed in a notebook
592+
using ``HTML()``
583593
- invokes the draw() method of every object in the display list
584594
"""
585595

@@ -601,8 +611,11 @@ def update(frame, a):
601611
self.done = False
602612
if self.trajectory is not None:
603613
nframes = len(self.trajectory)
604-
ani = animation.FuncAnimation(
605-
fig=plt.gcf(),
614+
615+
global _ani
616+
fig = plt.gcf()
617+
_ani = animation.FuncAnimation(
618+
fig=fig,
606619
func=update,
607620
frames=range(0, nframes),
608621
fargs=(self,),
@@ -611,17 +624,19 @@ def update(frame, a):
611624
repeat=repeat,
612625
)
613626

614-
if movie is None:
615-
while repeat or not self.done:
616-
plt.pause(1)
617-
else:
627+
if movie is True:
628+
plt.close(fig)
629+
return _ani.to_html5_video()
630+
elif isinstance(movie, str):
618631
# Set up formatting for the movie files
619632
if os.path.exists(movie):
620633
print("overwriting movie", movie)
621634
else:
622635
print("creating movie", movie)
623636
FFwriter = animation.FFMpegWriter(fps=10, extra_args=["-vcodec", "libx264"])
624-
ani.save(movie, writer=FFwriter)
637+
_ani.save(movie, writer=FFwriter)
638+
639+
return _ani
625640

626641
def __repr__(self):
627642
"""

spatialmath/base/transforms3d.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3065,7 +3065,7 @@ def tranimate(T, **kwargs):
30653065
pass
30663066

30673067
anim.trplot(T, **kwargs)
3068-
anim.run(**kwargs)
3068+
return anim.run(**kwargs)
30693069

30703070
# plt.show(block=block)
30713071

0 commit comments

C 3034 omments
 (0)
0