Skip to content

Commit 0a0b061

Browse files
committed
Allow eddyAnim to display field in color
1 parent 25df7b6 commit 0a0b061

File tree

2 files changed

+86
-15
lines changed

2 files changed

+86
-15
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Added
1919
- Add a filter option in EddyId to be able to remove fine scale (like noise) with same filter order than high scale
2020
filter
2121
- Add **EddyQuickCompare** to have few figures about several datasets in comparison based on match function
22+
- Color field for contour in **EddyAnim** could be choose
2223

2324
[3.3.0] - 2020-12-03
2425
--------------------

src/py_eddy_tracker/appli/gui.py

Lines changed: 85 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,24 @@
33
Entry point of graphic user interface
44
"""
55

6+
import logging
67
from datetime import datetime
8+
from itertools import chain
79

810
from matplotlib import pyplot
911
from matplotlib.collections import LineCollection
10-
from numpy import arange, empty, where
12+
from numpy import where
1113

1214
from .. import EddyParser
13-
from ..generic import flatten_line_matrix
1415
from ..gui import GUI
1516
from ..observations.tracking import TrackEddiesObservations
1617
from ..poly import create_vertice
1718

19+
logger = logging.getLogger("pet")
20+
1821

1922
class 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

Comments
 (0)