15
15
import matplotlib .pyplot as plt
16
16
from mpl_toolkits .mplot3d import Axes3D
17
17
from matplotlib import animation
18
- import spatialmath . base as tr
18
+ from spatialmath import base as tr
19
19
import numpy as np
20
20
import math
21
21
22
22
23
23
class Animate :
24
24
"""
25
25
Animate objects for matplotlib 3d
26
-
26
+
27
27
An instance of this class behaves like an Axes3D and supports proxies for
28
-
28
+
29
29
- ``plot``
30
30
- ``quiver``
31
31
- ``text``
32
-
33
- which renders them and also places corresponding objects into a display list.
34
- These objects are ``Line``, ``Quiver`` and ``Text``. Only these primitives will
35
- be animated.
36
-
37
- The objects are all drawn relative to the origin, and will be transformed according
38
- to the transform that is being animated.
39
-
32
+
33
+ which renders them and also places corresponding objects into a display
34
+ list. These objects are ``Line``, ``Quiver`` and ``Text``. Only these
35
+ primitives will be animated.
36
+
37
+ The objects are all drawn relative to the origin, and will be transformed
38
+ according to the transform that is being animated.
39
+
40
40
Example::
41
-
41
+
42
42
anim = animate.Animate(dims=[0,2]) # set up the 3D axes
43
43
anim.trplot(T, frame='A', color='green') # draw the frame
44
44
anim.run(loop=True) # animate it
@@ -50,14 +50,15 @@ def __init__(self, axes=None, dims=None, projection='ortho', labels=['X', 'Y', '
50
50
51
51
:param axes: the axes to plot into, defaults to current axes
52
52
:type axes: Axes3D reference
53
- :param dims: dimension of plot volume as [xmin, xmax, ymin, ymax,zmin, zmax].
54
- If dims is [min, max] those limits are applied to the x-, y- and z-axes.
53
+ :param dims: dimension of plot volume as [xmin, xmax, ymin, ymax,
54
+ zmin, zmax]. If dims is [min, max] those limits are applied
55
+ to the x-, y- and z-axes.
55
56
:type dims: array_like
56
57
:param projection: 3D projection: ortho [default] or persp
57
58
:type projection: str
58
59
:param labels: labels for the axes, defaults to X, Y and Z
59
60
:type labels: 3-tuple of strings
60
-
61
+
61
62
Will setup to plot into an existing or a new Axes3D instance.
62
63
63
64
"""
@@ -88,17 +89,17 @@ def __init__(self, axes=None, dims=None, projection='ortho', labels=['X', 'Y', '
88
89
self .ax = axes
89
90
90
91
# set flag for 2d or 3d axes, flag errors on the methods called later
91
-
92
+
92
93
def trplot (self , T , ** kwargs ):
93
94
"""
94
95
Define the transform to animate
95
-
96
+
96
97
:param T: an SO(3) or SE(3) pose to be displayed as coordinate frame
97
98
:type: numpy.ndarray, shape=(3,3) or (4,4)
98
-
99
- Is polymorphic with ``base.trplot`` and accepts the same parameters. This sets
100
- up the animation but doesn't execute it.
101
-
99
+
100
+ Is polymorphic with ``base.trplot`` and accepts the same parameters.
101
+ This sets up the animation but doesn't execute it.
102
+
102
103
:seealso: :func:`run`
103
104
104
105
"""
@@ -113,7 +114,7 @@ def trplot(self, T, **kwargs):
113
114
def run (self , movie = None , axes = None , repeat = True , interval = 50 , nframes = 100 , ** kwargs ):
114
115
"""
115
116
Run the animation
116
-
117
+
117
118
:param interval: number of steps in the animation [defaault 100]
118
119
:type interval: int
119
120
:param repeat: animate in endless loop [default False]
@@ -122,17 +123,19 @@ def run(self, movie=None, axes=None, repeat=True, interval=50, nframes=100, **kw
122
123
:type interval: int
123
124
:param movie: name of file to write MP4 movie into
124
125
:type movie: str
125
-
126
- Animates a 3D coordinate frame moving from the world frame to a frame represented by the SO(3) or SE(3) matrix to the current axes.
127
-
126
+
127
+ Animates a 3D coordinate frame moving from the world frame to a frame
128
+ represented by the SO(3) or SE(3) matrix to the current axes.
129
+
128
130
Notes:
129
-
130
- - the ``movie`` option requires the ffmpeg package to be installed: ``conda install -c conda-forge ffmpeg``
131
+
132
+ - the ``movie`` option requires the ffmpeg package to be installed:
133
+ ``conda install -c conda-forge ffmpeg``
131
134
- invokes the draw() method of every object in the display list
132
135
"""
133
-
136
+
134
137
def update (frame , a ):
135
- T = tr .trinterp (self .T , s = frame / nframes )
138
+ T = tr .trinterp (self .T , s = frame / nframes )
136
139
a ._draw (T )
137
140
return a .artists ()
138
141
@@ -170,14 +173,12 @@ def artists(self):
170
173
:rtype: list
171
174
"""
172
175
return [x .h for x in self .displaylist ]
173
-
174
176
175
177
def _draw (self , T ):
176
178
for x in self .displaylist :
177
179
x .draw (T )
178
180
179
-
180
- #------------------- plot()
181
+ # ------------------- plot()
181
182
182
183
class _Line :
183
184
@@ -196,25 +197,25 @@ def draw(self, T):
196
197
def plot (self , x , y , z , * args , ** kwargs ):
197
198
"""
198
199
Plot a polyline
199
-
200
+
200
201
:param x: list of x-coordinates
201
202
:type x: array_like
202
203
:param y: list of y-coordinates
203
204
:type y: array_like
204
205
:param z: list of z-coordinates
205
206
:type z: array_like
206
-
207
+
207
208
Other arguments as accepted by the matplotlib method.
208
-
209
+
209
210
All arrays must have the same length.
210
-
211
+
211
212
:seealso: :func:`matplotlib.pyplot.plot`
212
213
"""
213
214
214
215
h , = self .ax .plot (x , y , z , * args , ** kwargs )
215
216
self .displaylist .append (Animate ._Line (self , h , x , y , z ))
216
217
217
- #------------------- quiver()
218
+ # ------------------- quiver()
218
219
219
220
class _Quiver :
220
221
@@ -243,7 +244,7 @@ def draw(self, T):
243
244
def quiver (self , x , y , z , u , v , w , * args , ** kwargs ):
244
245
"""
245
246
Plot a quiver
246
-
247
+
247
248
:param x: list of base x-coordinates
248
249
:type x: array_like
249
250
:param y: list of base y-coordinates
@@ -256,19 +257,19 @@ def quiver(self, x, y, z, u, v, w, *args, **kwargs):
256
257
:type v: array_like
257
258
:param w: list of vector z-coordinates
258
259
:type w: array_like
259
-
260
- Draws a series of arrows, the bases defined by corresponding elements of
261
- (x,y,z) and the vector has components defined by corresponding elements of
262
- (u,v,w).
263
-
260
+
261
+ Draws a series of arrows, the bases defined by corresponding elements
262
+ of (x,y,z) and the vector has components defined by corresponding
263
+ elements of (u,v,w).
264
+
264
265
Other arguments as accepted by the matplotlib method.
265
-
266
+
266
267
:seealso: :func:`matplotlib.pyplot.quiver`
267
268
"""
268
269
h = self .ax .quiver (x , y , z , u , v , w , * args , ** kwargs )
269
270
self .displaylist .append (Animate ._Quiver (self , h ))
270
271
271
- #------------------- text()
272
+ # ------------------- text()
272
273
273
274
class _Text :
274
275
10BC0
@@ -280,30 +281,31 @@ def __init__(self, anim, h, x, y, z):
280
281
281
282
def draw (self , T ):
282
283
p = T @ self .p
283
- # x2, y2, _ = proj3d.proj_transform(p[0], p[1], p[2], self.anim.ax.get_proj())
284
+ # x2, y2, _ = proj3d.proj_transform(
285
+ # p[0], p[1], p[2], self.anim.ax.get_proj())
284
286
# self.h.set_position((x2, y2))
285
287
self .h .set_position ((p [0 ], p [1 ]))
286
288
self .h .set_3d_properties (z = p [2 ], zdir = 'x' )
287
289
288
290
def text (self , x , y , z , * args , ** kwargs ):
289
291
"""
290
292
Plot text
291
-
293
+
292
294
:param x: x-coordinate
293
295
:type x: float
294
296
:param y: float
295
297
:type y: array_like
296
298
:param z: z-coordinate
297
299
:type z: float
298
-
300
+
299
301
Other arguments as accepted by the matplotlib method.
300
-
302
+
301
303
:seealso: :func:`matplotlib.pyplot.text`
302
304
"""
303
305
h = self .ax .text3D (x , y , z , * args , ** kwargs )
304
306
self .displaylist .append (Animate ._Text (self , h , x , y , z ))
305
307
306
- #------------------- scatter()
308
+ # ------------------- scatter()
307
309
308
310
def scatter (self , ** kwargs ):
309
311
pass
0 commit comments