Skip to content

Commit f1e56ad

Browse files
committed
Application to animate eddy
1 parent d5933e1 commit f1e56ad

File tree

2 files changed

+114
-8
lines changed

2 files changed

+114
-8
lines changed

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
console_scripts=[
4141
"MergeEddies = py_eddy_tracker.appli:merge_eddies",
4242
"EddyNetworkGroup = py_eddy_tracker.network:build_network",
43+
"EddyAnim = py_eddy_tracker.appli:anim"
4344
]
4445
),
4546
package_data={

src/py_eddy_tracker/appli.py

Lines changed: 113 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,134 @@
2121
===========================================================================
2222
"""
2323

24+
from numpy import arange
25+
from matplotlib import pyplot
26+
from netCDF4 import Dataset
27+
from matplotlib.collections import LineCollection
28+
from py_eddy_tracker.poly import create_vertice
2429
from py_eddy_tracker import EddyParser
2530
from py_eddy_tracker.observations.tracking import TrackEddiesObservations
26-
from netCDF4 import Dataset
2731

2832

2933
def merge_eddies():
30-
parser = EddyParser('Merge eddies')
31-
parser.add_argument('filename', nargs='+', help='all file to merge')
32-
parser.add_argument('out', help='output file')
33-
parser.add_argument('--add_rotation_variable', help='add rotation variables', action='store_true')
34-
parser.add_argument('--include_var', nargs='+', type=str, help='use only listed variable')
34+
parser = EddyParser("Merge eddies")
35+
parser.add_argument("filename", nargs="+", help="all file to merge")
36+
parser.add_argument("out", help="output file")
37+
parser.add_argument(
38+
"--add_rotation_variable", help="add rotation variables", action="store_true"
39+
)
40+
parser.add_argument(
41+
"--include_var", nargs="+", type=str, help="use only listed variable"
42+
)
3543
args = parser.parse_args()
3644

3745
if args.include_var is None:
3846
with Dataset(args.filename[0]) as h:
3947
args.include_var = h.variables.keys()
4048

41-
obs = TrackEddiesObservations.load_file(args.filename[0], raw_data=True, include_vars=args.include_var)
49+
obs = TrackEddiesObservations.load_file(
50+
args.filename[0], raw_data=True, include_vars=args.include_var
51+
)
4252
if args.add_rotation_variable:
4353
obs = obs.add_rotation_type()
4454
for filename in args.filename[1:]:
45-
other = TrackEddiesObservations.load_file(filename, raw_data=True, include_vars=args.include_var)
55+
other = TrackEddiesObservations.load_file(
56+
filename, raw_data=True, include_vars=args.include_var
57+
)
4658
if args.add_rotation_variable:
4759
other = other.add_rotation_type()
4860
obs = obs.merge(other)
4961
obs.write_file(filename=args.out)
62+
63+
64+
def anim():
65+
parser = EddyParser("Merge eddies")
66+
parser.add_argument("filename", help="eddy atlas")
67+
parser.add_argument("id", help="Track id to anim", type=int)
68+
parser.add_argument(
69+
"--intern",
70+
action="store_true",
71+
help="display intern contour inplace of outter contour",
72+
)
73+
parser.add_argument(
74+
"--keep_step", default=25, help="number maximal of step displayed", type=int
75+
)
76+
parser.add_argument("--cmap", help="matplotlib colormap used")
77+
parser.add_argument(
78+
"--time_sleep",
79+
type=float,
80+
default=0.01,
81+
help="Sleeping time in second between 2 frame",
82+
)
83+
parser.add_argument(
84+
"--infinity_loop", action="store_true", help="Press Escape key to stop loop"
85+
)
86+
args = parser.parse_args()
87+
88+
atlas = TrackEddiesObservations.load_file(args.filename)
89+
eddy = atlas.extract_ids([args.id])
90+
x_name, y_name = eddy.intern(args.intern)
91+
t0, t1 = eddy.period
92+
t, x, y = eddy.time, eddy[x_name], eddy[y_name]
93+
x_min, x_max = x.min(), x.max()
94+
d_x = x_max - x_min
95+
x_min -= 0.05 * d_x
96+
x_max += 0.05 * d_x
97+
y_min, y_max = y.min(), y.max()
98+
d_y = y_max - y_min
99+
y_min -= 0.05 * d_y
100+
y_max += 0.05 * d_y
101+
102+
# General value
103+
cmap = pyplot.get_cmap(args.cmap)
104+
colors = cmap(arange(args.keep_step + 1) / args.keep_step)
105+
106+
# plot
107+
fig = pyplot.figure()
108+
# manager = plt.get_current_fig_manager()
109+
# fig.window.showMaximized()
110+
ax = fig.add_axes((0.05, 0.05, 0.9, 0.9))
111+
ax.set_xlim(x_min, x_max)
112+
ax.set_ylim(y_min, y_max)
113+
ax.set_aspect("equal")
114+
ax.grid()
115+
# # init mappable
116+
txt = ax.text(16.6, 36.8, "", zorder=10)
117+
c = LineCollection([], zorder=1)
118+
ax.add_collection(c)
119+
120+
fig.canvas.draw()
121+
fig.canvas.mpl_connect("key_press_event", keyboard)
122+
pyplot.show(block=False)
123+
# save background for future bliting
124+
bg_cache = fig.canvas.copy_from_bbox(ax.bbox)
125+
loop = True
126+
while loop:
127+
segs = list()
128+
# display contour every day
129+
for t_ in range(t0, t1 + 1, 1):
130+
fig.canvas.restore_region(bg_cache)
131+
# select contour for this time step
132+
m = t == t_
133+
if m.sum():
134+
segs.append(create_vertice(x[m][0], y[m][0]))
135+
c.set_paths(segs)
136+
c.set_color(colors[-len(segs) :])
137+
txt.set_text(f"{t0} -> {t_} -> {t1}")
138+
ax.draw_artist(c)
139+
ax.draw_artist(txt)
140+
# Remove first segment to keep only T contour
141+
if len(segs) > args.keep_step:
142+
segs.pop(0)
143+
# paint updated artist
144+
fig.canvas.blit(ax.bbox)
145+
fig.canvas.start_event_loop(args.time_sleep)
146+
if args.infinity_loop:
147+
fig.canvas.start_event_loop(0.5)
148+
else:
149+
loop = False
150+
151+
152+
def keyboard(event):
153+
if event.key == "escape":
154+
exit()

0 commit comments

Comments
 (0)