Skip to content

Commit 4f7fbc4

Browse files
committed
update examples
1 parent 7b62de8 commit 4f7fbc4

File tree

13 files changed

+253
-61
lines changed

13 files changed

+253
-61
lines changed

examples/06_grid_manipulation/pet_advect.py

Lines changed: 84 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
55
Dummy advection which use only static geostrophic current, which didn't resolve the complex circulation of the ocean.
66
"""
7-
import numpy as np
7+
import re
8+
89
from matplotlib import pyplot as plt
910
from matplotlib.animation import FuncAnimation
11+
from numpy import arange, isnan, meshgrid, ones
1012

1113
import py_eddy_tracker.gui
1214
from py_eddy_tracker import data
@@ -32,7 +34,7 @@
3234
fig = plt.figure(figsize=(10, 5))
3335
ax = fig.add_axes([0, 0, 1, 1], projection="full_axes")
3436
ax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid()
35-
x, y = np.meshgrid(g.x_c, g.y_c)
37+
x, y = meshgrid(g.x_c, g.y_c)
3638
a.filled(ax, facecolors="r", alpha=0.1), c.filled(ax, facecolors="b", alpha=0.1)
3739
_ = ax.quiver(x.T, y.T, g.grid("u"), g.grid("v"), scale=20)
3840

@@ -41,7 +43,10 @@
4143
class VideoAnimation(FuncAnimation):
4244
def _repr_html_(self, *args, **kwargs):
4345
"""To get video in html and have a player"""
44-
return self.to_html5_video()
46+
content = self.to_html5_video()
47+
return re.sub(
48+
r'width="[0-9]*"\sheight="[0-9]*"', 'width="100%" height="100%"', content
49+
)
4550

4651
def save(self, *args, **kwargs):
4752
if args[0].endswith("gif"):
@@ -56,26 +61,27 @@ def save(self, *args, **kwargs):
5661
# %%
5762
# Anim
5863
# ----
59-
# Particules positions
60-
x, y = np.meshgrid(np.arange(13, 36, 0.125), np.arange(28, 40, 0.125))
64+
# Particles setup
65+
step_p = 1 / 8
66+
x, y = meshgrid(arange(13, 36, step_p), arange(28, 40, step_p))
6167
x, y = x.reshape(-1), y.reshape(-1)
6268
# Remove all original position that we can't advect at first place
63-
m = ~np.isnan(g.interp("u", x, y))
64-
x, y = x[m], y[m]
69+
m = ~isnan(g.interp("u", x, y))
70+
x0, y0 = x[m], y[m]
71+
x, y = x0.copy(), y0.copy()
6572

73+
# %%
6674
# Movie properties
67-
kwargs = dict(frames=np.arange(51), interval=90)
75+
kwargs = dict(frames=arange(51), interval=100)
6876
kw_p = dict(nb_step=2, time_step=21600)
6977
frame_t = kw_p["nb_step"] * kw_p["time_step"] / 86400.0
7078

7179

72-
def anim_ax(generator, **kw):
80+
# %%
81+
# Method
82+
def anim_ax(**kw):
7383
t = 0
74-
for _ in range(4):
75-
generator.__next__()
76-
t += frame_t
77-
78-
fig = plt.figure(figsize=(10, 5), dpi=64)
84+
fig = plt.figure(figsize=(10, 5), dpi=55)
7985
ax = fig.add_axes([0, 0, 1, 1], projection="full_axes")
8086
ax.set_xlim(19, 30), ax.set_ylim(31, 36.5), ax.grid()
8187
a.filled(ax, facecolors="r", alpha=0.1), c.filled(ax, facecolors="b", alpha=0.1)
@@ -94,20 +100,74 @@ def update(i_frame, t_step):
94100
# %%
95101
# Filament forward
96102
# ^^^^^^^^^^^^^^^^
97-
p = g.filament(x, y, "u", "v", **kw_p, filament_size=4, rk4=True)
98-
fig, txt, l, t = anim_ax(p, lw=0.5)
103+
# Draw 3 last position in one path for each particles.,
104+
# it could be run backward with `backward=True` option in filament method
105+
p = g.filament(x, y, "u", "v", **kw_p, filament_size=3)
106+
fig, txt, l, t = anim_ax(lw=0.5)
99107
ani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))
100108

101109
# %%
102-
# Filament backward
110+
# Particle forward
103111
# ^^^^^^^^^^^^^^^^^
104-
p = g.filament(x, y, "u", "v", **kw_p, filament_size=4, backward=True, rk4=True)
105-
fig, txt, l, t = anim_ax(p, lw=0.5)
112+
# Forward advection of particles
113+
p = g.advect(x, y, "u", "v", **kw_p)
114+
fig, txt, l, t = anim_ax(ls="", marker=".", markersize=1)
115+
ani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))
116+
117+
# %%
118+
# We get last position and run backward until original position
119+
p = g.advect(x, y, "u", "v", **kw_p, backward=True)
120+
fig, txt, l, _ = anim_ax(ls="", marker=".", markersize=1)
106121
ani = VideoAnimation(fig, update, **kwargs, fargs=(-frame_t,))
107122

108123
# %%
109-
# Particule forward
110-
# ^^^^^^^^^^^^^^^^^
111-
p = g.advect(x, y, "u", "v", **kw_p, rk4=True)
112-
fig, txt, l, t = anim_ax(p, ls="", marker=".", markersize=1)
113-
ani = VideoAnimation(fig, update, **kwargs, fargs=(frame_t,))
124+
# Particles stat
125+
# --------------
126+
127+
# %%
128+
# Time_step settings
129+
# ^^^^^^^^^^^^^^^^^^
130+
# Dummy experiment to test advection precision, we run particles 50 days forward and backward ad different time step
131+
# and we measure distance between new positions and original positions.
132+
fig = plt.figure()
133+
ax = fig.add_subplot(111)
134+
ax.grid()
135+
kw = dict(
136+
bins=arange(0, 50, 0.001),
137+
cumulative=True,
138+
weights=ones(x0.shape) / x0.shape[0] * 100.0,
139+
histtype="step",
140+
)
141+
for time_step in (10800, 21600, 43200, 86400):
142+
x, y = x0.copy(), y0.copy()
143+
kw_advect = dict(nb_step=int(50 * 86400 / time_step), time_step=time_step)
144+
g.advect(x, y, "u", "v", **kw_advect).__next__()
145+
g.advect(x, y, "u", "v", **kw_advect, backward=True).__next__()
146+
d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5
147+
ax.hist(d, **kw, label=f"{86400. / time_step:.0f} time step by day")
148+
ax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc="lower right")
149+
ax.set_title("Distance after 50 days forward and 50 days backward")
150+
ax.set_xlabel("Distance between original position and final position (in degrees)")
151+
_ = ax.set_ylabel("Percent of particles with distance lesser than")
152+
153+
# %%
154+
# Time duration
155+
# ^^^^^^^^^^^^^
156+
# We keep same time_step but change time duration
157+
fig = plt.figure()
158+
ax = fig.add_subplot(111)
159+
ax.grid()
160+
time_step = 10800
161+
for duration in (5, 50, 100):
162+
x, y = x0.copy(), y0.copy()
163+
kw_advect = dict(nb_step=int(duration * 86400 / time_step), time_step=time_step)
164+
g.advect(x, y, "u", "v", **kw_advect).__next__()
165+
g.advect(x, y, "u", "v", **kw_advect, backward=True).__next__()
166+
d = ((x - x0) ** 2 + (y - y0) ** 2) ** 0.5
167+
ax.hist(d, **kw, label=f"Time duration {duration} days")
168+
ax.set_xlim(0, 0.25), ax.set_ylim(0, 100), ax.legend(loc="lower right")
169+
ax.set_title(
170+
"Distance after N days forward and N days backward\nwith a time step of 1/8 days"
171+
)
172+
ax.set_xlabel("Distance between original position and final position (in degrees)")
173+
_ = ax.set_ylabel("Percent of particles with distance lesser than ")

examples/06_grid_manipulation/pet_lavd.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@
77
88
Method are described here:
99
10-
- Abernathey, Ryan, and George Haller. " Transport by Lagrangian Vortices in the Eastern Pacific", Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021, https://doi.org/10.1175/JPO-D-17-0102.1
11-
- `Transport by Coherent Lagrangian Vortices`_, R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019, Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop
10+
- Abernathey, Ryan, and George Haller. "Transport by Lagrangian Vortices in the Eastern Pacific",
11+
Journal of Physical Oceanography 48, 3 (2018): 667-685, accessed Feb 16, 2021,
12+
https://doi.org/10.1175/JPO-D-17-0102.1
13+
- `Transport by Coherent Lagrangian Vortices`_,
14+
R. Abernathey, Sinha A., Tarshish N., Liu T., Zhang C., Haller G., 2019,
15+
Talk a t the Sources and Sinks of Ocean Mesoscale Eddy Energy CLIVAR Workshop
1216
1317
.. _Transport by Coherent Lagrangian Vortices:
1418
https://usclivar.org/sites/default/files/meetings/2019/presentations/Aberernathey_CLIVAR.pdf

examples/10_tracking_diagnostics/pet_center_count.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262

6363
g_c.vars["count"] = ratio
6464
m = g_c.display(
65-
ax_ratio, name="count", vmin=0.1, vmax=10, norm=LogNorm(), cmap="coolwarm_r"
65+
ax_ratio, name="count", norm=LogNorm(vmin=0.1, vmax=10), cmap="coolwarm_r"
6666
)
6767
plt.colorbar(m, cax=fig.add_axes([0.94, 0.02, 0.01, 0.2]))
6868

examples/10_tracking_diagnostics/pet_pixel_used.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161

6262
g_c.vars["count"] = ratio
6363
m = g_c.display(
64-
ax_ratio, name="count", vmin=0.1, vmax=10, norm=LogNorm(), cmap="coolwarm_r"
64+
ax_ratio, name="count", norm=LogNorm(vmin=0.1, vmax=10), cmap="coolwarm_r"
6565
)
6666
plt.colorbar(m, cax=fig.add_axes([0.95, 0.02, 0.01, 0.2]))
6767

examples/14_generic_tools/pet_fit_contour.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
# Load example identification file
2222
a = EddiesObservations.load_file(data.get_path("Anticyclonic_20190223.nc"))
2323

24+
2425
# %%
2526
# Function to draw circle or ellips from parameter
2627
def build_circle(x0, y0, r):

examples/16_network/pet_atlas.py

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,16 @@
66
from numpy import ma
77

88
import py_eddy_tracker.gui
9+
from py_eddy_tracker.data import get_path
910
from py_eddy_tracker.observations.network import NetworkObservations
1011

11-
n = NetworkObservations.load_file(
12-
"/data/adelepoulle/work/Eddies/20201217_network_build/tracking/med/Anticyclonic_seg.nc"
13-
)
14-
12+
n = NetworkObservations.load_file(get_path("Anticyclonic_seg.nc"))
1513
# %%
1614
# Parameters
1715
step = 1 / 10.0
1816
bins = ((-10, 37, step), (30, 46, step))
1917
kw_time = dict(cmap="terrain_r", factor=100.0 / n.nb_days, name="count")
20-
kw_ratio = dict(cmap=plt.get_cmap("magma_r", 10))
18+
kw_ratio = dict(cmap=plt.get_cmap("viridis", 10))
2119

2220

2321
# %%
@@ -149,16 +147,26 @@ def update_axes(ax, mappable=None):
149147
ax,
150148
**kw_ratio,
151149
vmin=0,
152-
vmax=1,
150+
vmax=5,
153151
name=g_all_merging.vars["count"] * 100.0 / g_all.vars["count"]
154152
)
155153
update_axes(ax, m).set_label("Pixel used in % all atlas")
156154

155+
# %%
156+
# Merging in networks longer than 10 days, with dead end remove (shorter than 5 days)
157+
# -----------------------------------------------------------------------------------
158+
ax = start_axes("")
159+
merger = n10.remove_dead_end(nobs=10).merging_event()
160+
g_10_merging = merger.grid_count(bins)
161+
m = g_10_merging.display(ax, **kw_time, vmin=0, vmax=1)
162+
update_axes(ax, m).set_label("Pixel used in % of time")
163+
157164
# %%
158165
# Merging in networks longer than 10 days
159166
# ---------------------------------------
160167
ax = start_axes("")
161-
g_10_merging = n10.merging_event().grid_count(bins)
168+
merger = n10.merging_event()
169+
g_10_merging = merger.grid_count(bins)
162170
m = g_10_merging.display(ax, **kw_time, vmin=0, vmax=1)
163171
update_axes(ax, m).set_label("Pixel used in % of time")
164172
# %%
@@ -167,10 +175,52 @@ def update_axes(ax, mappable=None):
167175
ax,
168176
**kw_ratio,
169177
vmin=0,
170-
vmax=2,
178+
vmax=5,
171179
name=ma.array(
172180
g_10_merging.vars["count"] * 100.0 / g_10.vars["count"],
173181
mask=g_10.vars["count"] < 365,
174182
)
175183
)
176184
update_axes(ax, m).set_label("Pixel used in % all atlas")
185+
186+
# %%
187+
# All Spliting
188+
# ------------
189+
# Display the occurence of spliting events
190+
ax = start_axes("")
191+
g_all_spliting = n.spliting_event().grid_count(bins)
192+
m = g_all_spliting.display(ax, **kw_time, vmin=0, vmax=1)
193+
update_axes(ax, m).set_label("Pixel used in % of time")
194+
195+
# %%
196+
# Ratio merging events / eddy presence
197+
ax = start_axes("")
198+
m = g_all_spliting.display(
199+
ax,
200+
**kw_ratio,
201+
vmin=0,
202+
vmax=5,
203+
name=g_all_spliting.vars["count"] * 100.0 / g_all.vars["count"]
204+
)
205+
update_axes(ax, m).set_label("Pixel used in % all atlas")
206+
207+
# %%
208+
# Spliting in networks longer than 10 days
209+
# ----------------------------------------
210+
ax = start_axes("")
211+
g_10_spliting = n10.spliting_event().grid_count(bins)
212+
m = g_10_spliting.display(ax, **kw_time, vmin=0, vmax=1)
213+
update_axes(ax, m).set_label("Pixel used in % of time")
214+
# %%
215+
ax = start_axes("")
216+
m = g_10_spliting.display(
217+
ax,
218+
**kw_ratio,
219+
vmin=0,
220+
vmax=5,
221+
name=ma.array(
222+
g_10_spliting.vars["count"] * 100.0 / g_10.vars["count"],
223+
mask=g_10.vars["count"] < 365,
224+
)
225+
)
226+
update_axes(ax, m).set_label("Pixel used in % all atlas")

examples/16_network/pet_ioannou_2017_case.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@
1212
from datetime import datetime, timedelta
1313

1414
import numpy as np
15+
from matplotlib import colors
1516
from matplotlib import pyplot as plt
1617
from matplotlib.animation import FuncAnimation
1718
from matplotlib.ticker import FuncFormatter
18-
from matplotlib import colors
1919

2020
import py_eddy_tracker.gui
2121
from py_eddy_tracker.appli.gui import Anim
22+
from py_eddy_tracker.data import get_path
2223
from py_eddy_tracker.observations.network import NetworkObservations
2324

2425

@@ -71,9 +72,7 @@ def update_axes(ax, mappable=None):
7172
# We know the position and the time of a specific eddy
7273
#
7374
# `n.extract_with_mask` give us the corresponding network
74-
n = NetworkObservations.load_file(
75-
"med/Anticyclonic_seg.nc"
76-
)
75+
n = NetworkObservations.load_file(get_path("Anticyclonic_seg.nc"))
7776
i = np.where(
7877
(n.lat > 33)
7978
* (n.lat < 34)

examples/16_network/pet_relative.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555

5656
# %%
5757
# Timeline by mean Effective Radius
58-
# -----------------------
58+
# ---------------------------------
5959
# The factor argument is applied on the chosen field
6060
fig = plt.figure(figsize=(15, 5))
6161
ax = fig.add_axes([0.04, 0.04, 0.92, 0.92])
@@ -237,7 +237,7 @@
237237

238238
# %%
239239
# Get birth event
240-
# ------------------
240+
# ---------------
241241
# Display the starting position of non-splitted eddies
242242
fig = plt.figure(figsize=(15, 8))
243243
ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes")
@@ -248,7 +248,7 @@
248248

249249
# %%
250250
# Get death event
251-
# ------------------
251+
# ---------------
252252
# Display the last position of non-merged eddies
253253
fig = plt.figure(figsize=(15, 8))
254254
ax = fig.add_axes([0.04, 0.06, 0.90, 0.88], projection="full_axes")

examples/16_network/pet_replay_segmentation.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@
1111
from datetime import datetime, timedelta
1212

1313
import numpy as np
14+
from matplotlib import colors
1415
from matplotlib import pyplot as plt
1516
from matplotlib.animation import FuncAnimation
1617
from matplotlib.ticker import FuncFormatter
17-
from matplotlib import colors
1818

1919
import py_eddy_tracker.gui
2020
from py_eddy_tracker.appli.gui import Anim
21+
from py_eddy_tracker.data import get_path
2122
from py_eddy_tracker.observations.network import NetworkObservations
2223
from py_eddy_tracker.observations.tracking import TrackEddiesObservations
2324

@@ -120,9 +121,7 @@ def get_obs(dataset):
120121

121122
# %%
122123
# Get original network, we will isolate only relative at order *2*
123-
n = NetworkObservations.load_file(
124-
"/data/adelepoulle/work/Eddies/20201217_network_build/tracking/med/Anticyclonic_seg.nc"
125-
)
124+
n = NetworkObservations.load_file(get_path("Anticyclonic_seg.nc"))
126125

127126
n = n.extract_with_mask(n.track == n.track[get_obs(n)])
128127
n_ = n.relative(get_obs(n), order=2)

0 commit comments

Comments
 (0)