Skip to content

Commit 16691a2

Browse files
committed
Add tools for network
Add option for EddyAnim to make video
1 parent 40ef190 commit 16691a2

File tree

4 files changed

+305
-38
lines changed

4 files changed

+305
-38
lines changed

examples/16_network/pet_relative.py

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,108 @@
2323

2424
# %%
2525
# Display timeline
26-
fig = plt.figure(figsize=(15, 8))
26+
fig = plt.figure(figsize=(15, 5))
2727
ax = fig.add_axes([0.04, 0.04, 0.92, 0.92])
2828
n.display_timeline(ax)
2929

3030
# %%
31-
# Display timeline with event
32-
fig = plt.figure(figsize=(15, 8))
31+
# Display timeline without event
32+
fig = plt.figure(figsize=(15, 5))
3333
ax = fig.add_axes([0.04, 0.04, 0.92, 0.92])
34-
n.display_timeline(ax, event=True)
35-
plt.show()
34+
n.display_timeline(ax, event=False)
35+
36+
# %%
37+
# Parameters timeline
38+
# -------------------
39+
kw = dict(s=25, cmap="Spectral_r", zorder=10)
40+
fig = plt.figure(figsize=(15, 8))
41+
ax = fig.add_axes([0.04, 0.54, 0.90, 0.44])
42+
m = n.scatter_timeline(ax, "radius_e", factor=1e-3, vmin=50, vmax=150, **kw)
43+
cb = plt.colorbar(
44+
m["scatter"], cax=fig.add_axes([0.95, 0.54, 0.01, 0.44]), orientation="vertical"
45+
)
46+
cb.set_label("Effective radius (km)")
47+
48+
ax = fig.add_axes([0.04, 0.04, 0.90, 0.44])
49+
m = n.scatter_timeline(ax, "amplitude", factor=100, vmin=0, vmax=15, **kw)
50+
cb = plt.colorbar(
51+
m["scatter"], cax=fig.add_axes([0.95, 0.04, 0.01, 0.44]), orientation="vertical"
52+
)
53+
cb.set_label("Amplitude (cm)")
54+
55+
# %%
56+
fig = plt.figure(figsize=(15, 5))
57+
ax = fig.add_axes([0.04, 0.06, 0.90, 0.88])
58+
m = n.scatter_timeline(ax, "speed_average", factor=100, vmin=0, vmax=40, **kw)
59+
cb = plt.colorbar(
60+
m["scatter"], cax=fig.add_axes([0.95, 0.04, 0.01, 0.92]), orientation="vertical"
61+
)
62+
cb.set_label("Maximum speed (cm/s)")
63+
64+
# %%
65+
fig = plt.figure(figsize=(15, 5))
66+
ax = fig.add_axes([0.04, 0.06, 0.90, 0.88])
67+
m = n.scatter_timeline(ax, "radius_s", factor=1e-3, vmin=20, vmax=100, **kw)
68+
cb = plt.colorbar(
69+
m["scatter"], cax=fig.add_axes([0.95, 0.04, 0.01, 0.92]), orientation="vertical"
70+
)
71+
cb.set_label("Speed radius (km)")
72+
73+
# %%
74+
# Remove dead branch
75+
# ------------------
76+
# Remove all tiny segment with less than N obs which didn't join two segments
77+
#
78+
# .. warning::
79+
# Must be explore, no solution to solve all the case
80+
81+
n_clean = n.remove_dead_branch(nobs=51)
82+
fig = plt.figure(figsize=(15, 8))
83+
ax = fig.add_axes([0.04, 0.54, 0.90, 0.40])
84+
ax.set_title(f"Original network ({n.infos()})")
85+
n.display_timeline(ax)
86+
ax = fig.add_axes([0.04, 0.04, 0.90, 0.40])
87+
ax.set_title(f"Clean network ({n_clean.infos()})")
88+
_ = n_clean.display_timeline(ax)
3689

3790
# %%
3891
# Keep close relative
3992
# -------------------
4093
# First choose an observation in the network
94+
fig = plt.figure(figsize=(15, 5))
95+
ax = fig.add_axes([0.04, 0.06, 0.90, 0.88])
96+
n.display_timeline(ax)
97+
i = 1100
98+
obs_args = n.time[i], n.segment[i]
99+
obs_kw = dict(color="black", markersize=30, marker=".")
100+
_ = ax.plot(*obs_args, **obs_kw)
101+
102+
# %%
103+
fig = plt.figure(figsize=(15, 5))
104+
ax = fig.add_axes([0.04, 0.06, 0.90, 0.88])
105+
m = n.scatter_timeline(
106+
ax, n.obs_relative_order(i), vmin=-1.5, vmax=6.5, cmap=plt.get_cmap("jet", 8), s=10
107+
)
108+
ax.plot(*obs_args, **obs_kw)
109+
cb = plt.colorbar(
110+
m["scatter"], cax=fig.add_axes([0.95, 0.04, 0.01, 0.92]), orientation="vertical"
111+
)
112+
cb.set_label("Relative order")
113+
# %%
114+
fig = plt.figure(figsize=(15, 5))
115+
ax = fig.add_axes([0.04, 0.06, 0.90, 0.88])
116+
close_to_i = n.relative(i, order=1)
117+
ax.set_title(f"Close segments ({close_to_i.infos()})")
118+
_ = close_to_i.display_timeline(ax)
119+
# %%
120+
fig = plt.figure(figsize=(15, 5))
121+
ax = fig.add_axes([0.04, 0.06, 0.90, 0.88])
122+
close_to_i = n.relative(i, order=2)
123+
ax.set_title(f"Close segments ({close_to_i.infos()})")
124+
_ = close_to_i.display_timeline(ax)
125+
# %%
126+
fig = plt.figure(figsize=(15, 5))
127+
ax = fig.add_axes([0.04, 0.06, 0.90, 0.88])
128+
close_to_i = n.relative(i, order=3)
129+
ax.set_title(f"Close segments ({close_to_i.infos()})")
130+
_ = close_to_i.display_timeline(ax)

src/py_eddy_tracker/appli/gui.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"""
55

66
import logging
7-
from datetime import datetime
7+
from datetime import datetime, timedelta
88
from itertools import chain
99

1010
from matplotlib import pyplot
@@ -176,7 +176,7 @@ def update(self):
176176
]
177177
)
178178
# Update date txt and info
179-
txt = f"{self.now}"
179+
txt = f"{(timedelta(int(self.now)) + datetime(1950,1,1)).strftime('%Y/%m/%d')}"
180180
if self.graphic_informations:
181181
txt += f"- {1/self.sleep_event:.0f} frame/s"
182182
self.txt.set_text(txt)
@@ -262,7 +262,7 @@ def anim():
262262
parser.add_argument(
263263
"--vmax", default=None, type=float, help="Upper bound to color contour"
264264
)
265-
parser.add_argument("--avi", help="Filename to save animation (avi)")
265+
parser.add_argument("--mp4", help="Filename to save animation (mp4)")
266266
args = parser.parse_args()
267267
variables = ["time", "track", "longitude", "latitude", args.field]
268268
variables.extend(TrackEddiesObservations.intern(args.intern, public_label=True))
@@ -284,6 +284,10 @@ def anim():
284284
(eddies.contour_lon_e.T - eddies.lon + 180) % 360 + eddies.lon - 180
285285
).T
286286

287+
kw = dict()
288+
if args.mp4:
289+
kw["figsize"] = (16, 9)
290+
kw["dpi"] = 120
287291
a = Anim(
288292
eddies,
289293
intern=args.intern,
@@ -293,13 +297,14 @@ def anim():
293297
field_color=args.field,
294298
range_color=(args.vmin, args.vmax),
295299
graphic_information=logger.getEffectiveLevel() == logging.DEBUG,
300+
**kw,
296301
)
297-
if args.avi is None:
302+
if args.mp4 is None:
298303
a.show(infinity_loop=args.infinity_loop)
299304
else:
300305
kwargs = dict(frames=arange(*a.period), interval=50)
301306
ani = FuncAnimation(a.fig, a.func_animation, **kwargs)
302-
ani.save(args.avi, fps=30, extra_args=["-vcodec", "libx264"])
307+
ani.save(args.mp4, fps=30, extra_args=["-vcodec", "libx264"])
303308

304309

305310
def gui_parser():

src/py_eddy_tracker/appli/network.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import logging
77

88
from .. import EddyParser
9-
from ..observations.network import Network
9+
from ..observations.network import Network, NetworkObservations
1010
from ..observations.tracking import TrackEddiesObservations
1111

1212
logger = logging.getLogger("pet")
@@ -50,7 +50,13 @@ def divide_network():
5050
args.input,
5151
include_vars=("time", "track", "latitude", "longitude", *contour_name),
5252
)
53-
ids = e.split_network(intern=args.intern, window=args.window, minimal_area=False)
54-
e = e.add_fields(("segment",))
55-
e.segment[:] = ids["track"]
56-
e.write_file(filename=args.out)
53+
n = NetworkObservations.from_split_network(
54+
e, e.split_network(intern=args.intern, window=args.window)
55+
)
56+
n.write_file(filename=args.out)
57+
58+
59+
def subsample_network():
60+
parser = EddyParser("Sub sample")
61+
parser.add_argument("input", help="input network file")
62+
parser.add_argument("out", help="output file")

0 commit comments

Comments
 (0)