1+ {
2+ "cells" : [
3+ {
4+ "cell_type" : " code" ,
5+ "execution_count" : null ,
6+ "metadata" : {
7+ "collapsed" : false
8+ },
9+ "outputs" : [],
10+ "source" : [
11+ " %matplotlib inline"
12+ ]
13+ },
14+ {
15+ "cell_type" : " markdown" ,
16+ "metadata" : {},
17+ "source" : [
18+ " \n # Ioannou case\n Figure 10 from https://doi.org/10.1002/2017JC013158\n "
19+ ]
20+ },
21+ {
22+ "cell_type" : " markdown" ,
23+ "metadata" : {},
24+ "source" : [
25+ " We want to find the Ierapetra Eddy described above in the networks\n\n "
26+ ]
27+ },
28+ {
29+ "cell_type" : " code" ,
30+ "execution_count" : null ,
31+ "metadata" : {
32+ "collapsed" : false
33+ },
34+ "outputs" : [],
35+ "source" : [
36+ " import re"
37+ ]
38+ },
39+ {
40+ "cell_type" : " code" ,
41+ "execution_count" : null ,
42+ "metadata" : {
43+ "collapsed" : false
44+ },
45+ "outputs" : [],
46+ "source" : [
47+ " from datetime import datetime, timedelta\n\n import numpy as np\n from matplotlib import colors\n from matplotlib import pyplot as plt\n from matplotlib.animation import FuncAnimation\n from matplotlib.ticker import FuncFormatter\n\n import py_eddy_tracker.gui\n from py_eddy_tracker.appli.gui import Anim\n from py_eddy_tracker.data import get_remote_sample\n from py_eddy_tracker.observations.network import NetworkObservations"
48+ ]
49+ },
50+ {
51+ "cell_type" : " code" ,
52+ "execution_count" : null ,
53+ "metadata" : {
54+ "collapsed" : false
55+ },
56+ "outputs" : [],
57+ "source" : [
58+ "class VideoAnimation(FuncAnimation):\n def _repr_html_(self, *args, **kwargs):\n \"\"\"To get video in html and have a player\"\"\"\n content = self.to_html5_video()\n return re.sub(\n r'width=\"[0-9]*\"\\sheight=\"[0-9]*\"', 'width=\"100%\" height=\"100%\"', content\n )\n\n def save(self, *args, **kwargs):\n if args[0].endswith(\"gif\"):\n # In this case gif is use to create thumbnail which are not use but consume same time than video\n # So we create an empty file, to save time\n with open(args[0], \"w\") as _:\n pass\n return\n return super().save(*args, **kwargs)\n\n\n@FuncFormatter\ndef formatter(x, pos):\n return (timedelta(x) + datetime(1950, 1, 1)).strftime(\"%d/%m/%Y\")\n\n\ndef start_axes(title=\"\"):\n fig = plt.figure(figsize=(13, 6))\n ax = fig.add_axes([0.03, 0.03, 0.90, 0.94], projection=\"full_axes\")\n ax.set_xlim(19, 29), ax.set_ylim(31, 35.5)\n ax.set_aspect(\"equal\")\n ax.set_title(title, weight=\"bold\")\n ax.update_env()\n return ax\n\n\ndef timeline_axes(title=\"\"):\n fig = plt.figure(figsize=(15, 5))\n ax = fig.add_axes([0.03, 0.06, 0.90, 0.88])\n ax.set_title(title, weight=\"bold\")\n ax.xaxis.set_major_formatter(formatter), ax.grid()\n return ax\n\n\ndef update_axes(ax, mappable=None):\n ax.grid(True)\n if mappable:\n return plt.colorbar(mappable, cax=ax.figure.add_axes([0.94, 0.05, 0.01, 0.9]))"
59+ ]
60+ },
61+ {
62+ "cell_type" : " markdown" ,
63+ "metadata" : {},
64+ "source" : [
65+ " We know the position and the time of a specific eddy\n\n `n.extract_with_mask` give us the corresponding network\n\n "
66+ ]
67+ },
68+ {
69+ "cell_type" : " code" ,
70+ "execution_count" : null ,
71+ "metadata" : {
72+ "collapsed" : false
73+ },
74+ "outputs" : [],
75+ "source" : [
76+ " n = NetworkObservations.load_file(\n get_remote_sample(\n \" eddies_med_adt_allsat_dt2018_err70_filt500_order1/Anticyclonic_network.nc\"\n )\n )\n i = np.where(\n (n.lat > 33)\n * (n.lat < 34)\n * (n.lon > 22)\n * (n.lon < 23)\n * (n.time > 20630)\n * (n.time < 20650)\n )[0][0]\n ioannou_case = n.extract_with_mask(n.track == n.track[i])\n print(ioannou_case.infos())"
77+ ]
78+ },
79+ {
80+ "cell_type" : " markdown" ,
81+ "metadata" : {},
82+ "source" : [
83+ " It seems that this network is huge! Our case is visible at 22E 33.5N\n\n "
84+ ]
85+ },
86+ {
87+ "cell_type" : " code" ,
88+ "execution_count" : null ,
89+ "metadata" : {
90+ "collapsed" : false
91+ },
92+ "outputs" : [],
93+ "source" : [
94+ " ax = start_axes()\n ioannou_case.plot(ax, color_cycle=ioannou_case.COLORS)\n update_axes(ax)"
95+ ]
96+ },
97+ {
98+ "cell_type" : " markdown" ,
99+ "metadata" : {},
100+ "source" : [
101+ " ## Full Timeline\n The network span for many years... How to cut the interesting part?\n\n "
102+ ]
103+ },
104+ {
105+ "cell_type" : " code" ,
106+ "execution_count" : null ,
107+ "metadata" : {
108+ "collapsed" : false
109+ },
110+ "outputs" : [],
111+ "source" : [
112+ " fig = plt.figure(figsize=(15, 5))\n ax = fig.add_axes([0.04, 0.05, 0.92, 0.92])\n ax.xaxis.set_major_formatter(formatter), ax.grid()\n _ = ioannou_case.display_timeline(ax)"
113+ ]
114+ },
115+ {
116+ "cell_type" : " markdown" ,
117+ "metadata" : {},
118+ "source" : [
119+ " ## Sub network and new numbering\n Here we chose to keep only the order 3 segments relatives to our chosen eddy\n\n "
120+ ]
121+ },
122+ {
123+ "cell_type" : " code" ,
124+ "execution_count" : null ,
125+ "metadata" : {
126+ "collapsed" : false
127+ },
128+ "outputs" : [],
129+ "source" : [
130+ " i = np.where(\n (ioannou_case.lat > 33)\n * (ioannou_case.lat < 34)\n * (ioannou_case.lon > 22)\n * (ioannou_case.lon < 23)\n * (ioannou_case.time > 20630)\n * (ioannou_case.time < 20650)\n )[0][0]\n close_to_i3 = ioannou_case.relative(i, order=3)\n close_to_i3.numbering_segment()"
131+ ]
132+ },
133+ {
134+ "cell_type" : " markdown" ,
135+ "metadata" : {},
136+ "source" : [
137+ " ## Anim\n Quick movie to see better!\n\n "
138+ ]
139+ },
140+ {
141+ "cell_type" : " code" ,
142+ "execution_count" : null ,
143+ "metadata" : {
144+ "collapsed" : false
145+ },
146+ "outputs" : [],
147+ "source" : [
148+ " cmap = colors.ListedColormap(\n list(close_to_i3.COLORS), name=\" from_list\" , N=close_to_i3.segment.max()\n )\n a = Anim(\n close_to_i3,\n figsize=(12, 4),\n cmap=cmap,\n nb_step=7,\n dpi=80,\n field_color=\" segment\" ,\n field_txt=\" segment\" ,\n )\n a.ax.set_xlim(19, 30), a.ax.set_ylim(32, 35.25)\n a.ax.update_env()\n a.txt.set_position((21.5, 32.7))\n kwargs = dict(frames=np.arange(*a.period), interval=100)\n ani = VideoAnimation(a.fig, a.func_animation, **kwargs)"
149+ ]
150+ },
151+ {
152+ "cell_type" : " markdown" ,
153+ "metadata" : {},
154+ "source" : [
155+ " ## Classic display\n\n "
156+ ]
157+ },
158+ {
159+ "cell_type" : " code" ,
160+ "execution_count" : null ,
161+ "metadata" : {
162+ "collapsed" : false
163+ },
164+ "outputs" : [],
165+ "source" : [
166+ " ax = timeline_axes()\n _ = close_to_i3.display_timeline(ax)"
167+ ]
168+ },
169+ {
170+ "cell_type" : " code" ,
171+ "execution_count" : null ,
172+ "metadata" : {
173+ "collapsed" : false
174+ },
175+ "outputs" : [],
176+ "source" : [
177+ " ax = start_axes(\"\" )\n n_copy = close_to_i3.copy()\n n_copy.position_filter(2, 4)\n n_copy.plot(ax, color_cycle=n_copy.COLORS)\n update_axes(ax)"
178+ ]
179+ },
180+ {
181+ "cell_type" : " markdown" ,
182+ "metadata" : {},
183+ "source" : [
184+ " ## Latitude Timeline\n\n "
185+ ]
186+ },
187+ {
188+ "cell_type" : " code" ,
189+ "execution_count" : null ,
190+ "metadata" : {
191+ "collapsed" : false
192+ },
193+ "outputs" : [],
194+ "source" : [
195+ " ax = timeline_axes(f\" Close segments ({close_to_i3.infos()})\" )\n n_copy = close_to_i3.copy()\n n_copy.median_filter(15, \" time\" , \" latitude\" )\n _ = n_copy.display_timeline(ax, field=\" lat\" , method=\" all\" )"
196+ ]
197+ },
198+ {
199+ "cell_type" : " markdown" ,
200+ "metadata" : {},
201+ "source" : [
202+ " ## Local radius timeline\n Effective (bold) and Speed (thin) Radius together\n\n "
203+ ]
204+ },
205+ {
206+ "cell_type" : " code" ,
207+ "execution_count" : null ,
208+ "metadata" : {
209+ "collapsed" : false
210+ },
211+ "outputs" : [],
212+ "source" : [
213+ " n_copy.median_filter(2, \" time\" , \" radius_e\" )\n n_copy.median_filter(2, \" time\" , \" radius_s\" )\n for b0, b1 in [\n (datetime(i, 1, 1), datetime(i, 12, 31)) for i in (2004, 2005, 2006, 2007)\n ]:\n ref, delta = datetime(1950, 1, 1), 20\n b0_, b1_ = (b0 - ref).days, (b1 - ref).days\n ax = timeline_axes()\n ax.set_xlim(b0_ - delta, b1_ + delta)\n ax.set_ylim(10, 115)\n ax.axvline(b0_, color=\" k\" , lw=1.5, ls=\" --\" ), ax.axvline(\n b1_, color=\" k\" , lw=1.5, ls=\" --\"\n )\n n_copy.display_timeline(\n ax, field=\" radius_e\" , method=\" all\" , lw=4, markersize=8, factor=1e-3\n )\n n_copy.display_timeline(\n ax, field=\" radius_s\" , method=\" all\" , lw=1, markersize=3, factor=1e-3\n )"
214+ ]
215+ },
216+ {
217+ "cell_type" : " markdown" ,
218+ "metadata" : {},
219+ "source" : [
220+ " ## Parameters timeline\n Effective Radius\n\n "
221+ ]
222+ },
223+ {
224+ "cell_type" : " code" ,
225+ "execution_count" : null ,
226+ "metadata" : {
227+ "collapsed" : false
228+ },
229+ "outputs" : [],
230+ "source" : [
231+ " kw = dict(s=35, cmap=plt.get_cmap(\" Spectral_r\" , 8), zorder=10)\n ax = timeline_axes()\n m = close_to_i3.scatter_timeline(ax, \" radius_e\" , factor=1e-3, vmin=20, vmax=100, **kw)\n cb = update_axes(ax, m[\" scatter\" ])\n cb.set_label(\" Effective radius (km)\" )"
232+ ]
233+ },
234+ {
235+ "cell_type" : " markdown" ,
236+ "metadata" : {},
237+ "source" : [
238+ " Shape error\n\n "
239+ ]
240+ },
241+ {
242+ "cell_type" : " code" ,
243+ "execution_count" : null ,
244+ "metadata" : {
245+ "collapsed" : false
246+ },
247+ "outputs" : [],
248+ "source" : [
249+ " ax = timeline_axes()\n m = close_to_i3.scatter_timeline(ax, \" shape_error_e\" , vmin=14, vmax=70, **kw)\n cb = update_axes(ax, m[\" scatter\" ])\n cb.set_label(\" Effective shape error\" )"
250+ ]
251+ }
252+ ],
253+ "metadata" : {
254+ "kernelspec" : {
255+ "display_name" : " Python 3" ,
256+ "language" : " python" ,
257+ "name" : " python3"
258+ },
259+ "language_info" : {
260+ "codemirror_mode" : {
261+ "name" : " ipython" ,
262+ "version" : 3
263+ },
264+ "file_extension" : " .py" ,
265+ "mimetype" : " text/x-python" ,
266+ "name" : " python" ,
267+ "nbconvert_exporter" : " python" ,
268+ "pygments_lexer" : " ipython3" ,
269+ "version" : " 3.7.7"
270+ }
271+ },
272+ "nbformat" : 4 ,
273+ "nbformat_minor" : 0
274+ }
0 commit comments