33Entry point of graphic user interface
44"""
55
6+ import logging
67from datetime import datetime
8+ from itertools import chain
79
810from matplotlib import pyplot
911from matplotlib .collections import LineCollection
10- from numpy import arange , empty , where
12+ from numpy import where
1113
1214from .. import EddyParser
13- from ..generic import flatten_line_matrix
1415from ..gui import GUI
1516from ..observations .tracking import TrackEddiesObservations
1617from ..poly import create_vertice
1718
19+ logger = logging .getLogger ("pet" )
20+
1821
1922class Anim :
23+
2024 def __init__ (
2125 self , eddy , intern = False , sleep_event = 0.1 , graphic_information = False , ** kwargs
2226 ):
@@ -29,11 +33,32 @@ def __init__(
2933 self .period = self .eddy .period
3034 self .sleep_event = sleep_event
3135 self .mappables = list ()
36+ self .field_color = None
37+ self .time_field = False
3238 self .setup (** kwargs )
3339
34- def setup (self , cmap = "jet" , nb_step = 25 , figsize = (8 , 6 ), ** kwargs ):
35- cmap = pyplot .get_cmap (cmap )
36- self .colors = cmap (arange (nb_step + 1 ) / nb_step )
40+ def setup (
41+ self ,
42+ cmap = "jet" ,
43+ lut = None ,
44+ field_color = "time" ,
45+ range_color = (None , None ),
46+ nb_step = 25 ,
47+ figsize = (8 , 6 ),
48+ ** kwargs ,
49+ ):
50+ self .field_color = self .eddy [field_color ].astype ("f4" )
51+ rg = range_color
52+ if rg [0 ] is None and rg [1 ] is None and field_color == "time" :
53+ self .time_field = True
54+ else :
55+ rg = (
56+ self .field_color .min () if rg [0 ] is None else rg [0 ],
57+ self .field_color .max () if rg [1 ] is None else rg [1 ],
58+ )
59+ self .field_color = (self .field_color - rg [0 ]) / (rg [1 ] - rg [0 ])
60+
61+ self .colors = pyplot .get_cmap (cmap , lut = lut )
3762 self .nb_step = nb_step
3863
3964 x_min , x_max = self .x_core .min () - 2 , self .x_core .max () + 2
@@ -51,6 +76,8 @@ def setup(self, cmap="jet", nb_step=25, figsize=(8, 6), **kwargs):
5176 # init mappable
5277 self .txt = self .ax .text (x_min + 0.05 * d_x , y_min + 0.05 * d_y , "" , zorder = 10 )
5378 self .segs = list ()
79+ self .t_segs = list ()
80+ self .c_segs = list ()
5481 self .contour = LineCollection ([], zorder = 1 )
5582 self .ax .add_collection (self .contour )
5683
@@ -89,8 +116,9 @@ def show(self, infinity_loop=False):
89116 if dt < 0 :
90117 # self.sleep_event = dt_draw * 1.01
91118 dt = 1e-10
119+ if dt == 0 :
120+ dt = 1e-10
92121 self .fig .canvas .start_event_loop (dt )
93-
94122 if self .now > t1 :
95123 break
96124 if infinity_loop :
@@ -118,20 +146,41 @@ def func_animation(self, frame):
118146 def update (self ):
119147 m = self .t == self .now
120148 if m .sum ():
121- self .segs .append (
122- create_vertice (
123- flatten_line_matrix (self .x [m ]), flatten_line_matrix (self .y [m ])
149+ segs = list ()
150+ t = list ()
151+ c = list ()
152+ for i in where (m )[0 ]:
153+ segs .append (create_vertice (self .x [i ], self .y [i ]))
154+ c .append (self .field_color [i ])
155+ t .append (self .now )
156+ self .segs .append (segs )
157+ self .c_segs .append (c )
158+ self .t_segs .append (t )
159+ self .contour .set_paths (chain (* self .segs ))
160+ if self .time_field :
161+ self .contour .set_color (
162+ self .colors (
163+ [
164+ (self .nb_step - self .now + i ) / self .nb_step
165+ for i in chain (* self .c_segs )
166+ ]
124167 )
125168 )
126169 else :
127- self .segs .append (empty ((0 , 2 )))
128- self .contour .set_paths (self .segs )
129- self .contour .set_color (self .colors [- len (self .segs ) :])
130- self .contour .set_lw (arange (len (self .segs )) / len (self .segs ) * 2.5 )
170+ self .contour .set_color (self .colors (list (chain (* self .c_segs ))))
171+ # linewidth will be link to time delay
172+ self .contour .set_lw (
173+ [
174+ (1 - (self .now - i ) / self .nb_step ) * 2.5 if i <= self .now else 0
175+ for i in chain (* self .t_segs )
176+ ]
177+ )
178+ # Update date txt and info
131179 txt = f"{ self .now } "
132180 if self .graphic_informations :
133181 txt += f"- { 1 / self .sleep_event :.0f} frame/s"
134182 self .txt .set_text (txt )
183+ # Update id txt
135184 for i in where (m )[0 ]:
136185 mappable = self .ax .text (
137186 self .x_core [i ], self .y_core [i ], self .track [i ], fontsize = 8
@@ -143,6 +192,8 @@ def update(self):
143192 # Remove first segment to keep only T contour
144193 if len (self .segs ) > self .nb_step :
145194 self .segs .pop (0 )
195+ self .t_segs .pop (0 )
196+ self .c_segs .pop (0 )
146197
147198 def draw_contour (self ):
148199 # select contour for this time step
@@ -165,8 +216,13 @@ def keyboard(self, event):
165216 elif event .key == "right" and self .pause :
166217 self .next ()
167218 elif event .key == "left" and self .pause :
219+ # we remove 2 step to add 1 so we rewind of only one
168220 self .segs .pop (- 1 )
169221 self .segs .pop (- 1 )
222+ self .t_segs .pop (- 1 )
223+ self .t_segs .pop (- 1 )
224+ self .c_segs .pop (- 1 )
225+ self .c_segs .pop (- 1 )
170226 self .prev ()
171227
172228
@@ -197,11 +253,22 @@ def anim():
197253 action = "store_true" ,
198254 help = "Longitude will be centered on first obs, if there are only one group." ,
199255 )
256+ parser .add_argument (
257+ "--field" , default = "time" , help = "Field use to color contour instead of time"
258+ )
259+ parser .add_argument (
260+ "--vmin" , default = None , type = float , help = "Inferior bound to color contour"
261+ )
262+ parser .add_argument (
263+ "--vmax" , default = None , type = float , help = "Upper bound to color contour"
264+ )
200265 args = parser .parse_args ()
201- variables = ["time" , "track" , "longitude" , "latitude" ]
266+ variables = ["time" , "track" , "longitude" , "latitude" , args . field ]
202267 variables .extend (TrackEddiesObservations .intern (args .intern , public_label = True ))
203268
204- eddies = TrackEddiesObservations .load_file (args .filename , include_vars = variables )
269+ eddies = TrackEddiesObservations .load_file (
270+ args .filename , include_vars = set (variables )
271+ )
205272 if not args .all :
206273 if len (args .id ) == 0 :
207274 raise Exception (
@@ -222,6 +289,9 @@ def anim():
222289 sleep_event = args .time_sleep ,
223290 cmap = args .cmap ,
224291 nb_step = args .keep_step ,
292+ field_color = args .field ,
293+ range_color = (args .vmin , args .vmax ),
294+ graphic_information = logger .getEffectiveLevel () == logging .DEBUG ,
225295 )
226296 a .show (infinity_loop = args .infinity_loop )
227297
0 commit comments