.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "python_module/16_network/pet_group_anim.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. or to run this example in your browser via Binder .. rst-class:: sphx-glr-example-title .. _sphx_glr_python_module_16_network_pet_group_anim.py: Network group process ===================== .. GENERATED FROM PYTHON SOURCE LINES 5-22 .. code-block:: Python from datetime import datetime # sphinx_gallery_thumbnail_number = 2 import re from matplotlib import pyplot as plt from matplotlib.animation import FuncAnimation from matplotlib.colors import ListedColormap from numba import njit from numpy import arange, array, empty, ones from py_eddy_tracker import data from py_eddy_tracker.generic import flatten_line_matrix from py_eddy_tracker.observations.network import Network from py_eddy_tracker.observations.observation import EddiesObservations .. GENERATED FROM PYTHON SOURCE LINES 23-41 .. code-block:: Python class VideoAnimation(FuncAnimation): def _repr_html_(self, *args, **kwargs): """To get video in html and have a player""" content = self.to_html5_video() return re.sub( r'width="[0-9]*"\sheight="[0-9]*"', 'width="100%" height="100%"', content ) def save(self, *args, **kwargs): if args[0].endswith("gif"): # In this case gif is used to create thumbnail which is not used but consume same time than video # So we create an empty file, to save time with open(args[0], "w") as _: pass return return super().save(*args, **kwargs) .. GENERATED FROM PYTHON SOURCE LINES 42-53 .. code-block:: Python NETWORK_GROUPS = list() @njit(cache=True) def apply_replace(x, x0, x1): nb = x.shape[0] for i in range(nb): if x[i] == x0: x[i] = x1 .. GENERATED FROM PYTHON SOURCE LINES 54-55 Modified class to catch group process at each step in order to illustrate processing .. GENERATED FROM PYTHON SOURCE LINES 55-90 .. code-block:: Python class MyNetwork(Network): def get_group_array(self, results, nb_obs): """With a loop on all pair of index, we will label each obs with a group number """ nb_obs = array(nb_obs, dtype="u4") day_start = nb_obs.cumsum() - nb_obs gr = empty(nb_obs.sum(), dtype="u4") gr[:] = self.NOGROUP id_free = 1 for i, j, ii, ij in results: gr_i = gr[slice(day_start[i], day_start[i] + nb_obs[i])] gr_j = gr[slice(day_start[j], day_start[j] + nb_obs[j])] # obs with no groups m = (gr_i[ii] == self.NOGROUP) * (gr_j[ij] == self.NOGROUP) nb_new = m.sum() gr_i[ii[m]] = gr_j[ij[m]] = arange(id_free, id_free + nb_new) id_free += nb_new # associate obs with no group with obs with group m = (gr_i[ii] != self.NOGROUP) * (gr_j[ij] == self.NOGROUP) gr_j[ij[m]] = gr_i[ii[m]] m = (gr_i[ii] == self.NOGROUP) * (gr_j[ij] != self.NOGROUP) gr_i[ii[m]] = gr_j[ij[m]] # case where 2 obs have a different group m = gr_i[ii] != gr_j[ij] if m.any(): # Merge of group, ref over etu for i_, j_ in zip(ii[m], ij[m]): g0, g1 = gr_i[i_], gr_j[j_] apply_replace(gr, g0, g1) NETWORK_GROUPS.append((i, j, gr.copy())) return gr .. GENERATED FROM PYTHON SOURCE LINES 91-92 Movie period .. GENERATED FROM PYTHON SOURCE LINES 92-95 .. code-block:: Python t0 = (datetime(2005, 5, 1) - datetime(1950, 1, 1)).days t1 = (datetime(2005, 6, 1) - datetime(1950, 1, 1)).days .. GENERATED FROM PYTHON SOURCE LINES 96-97 Get data from period and area .. GENERATED FROM PYTHON SOURCE LINES 97-101 .. code-block:: Python e = EddiesObservations.load_file(data.get_demo_path("network_med.nc")) e = e.extract_with_mask((e.time >= t0) * (e.time < t1)).extract_with_area( dict(llcrnrlon=25, urcrnrlon=35, llcrnrlat=31, urcrnrlat=37.5) ) .. GENERATED FROM PYTHON SOURCE LINES 102-103 Reproduce individual daily identification(for demonstration) .. GENERATED FROM PYTHON SOURCE LINES 103-109 .. code-block:: Python EDDIES_BY_DAYS = list() for i, b0, b1 in e.iter_on("time"): EDDIES_BY_DAYS.append(e.index(i)) # need for display e = EddiesObservations.concatenate(EDDIES_BY_DAYS) .. GENERATED FROM PYTHON SOURCE LINES 110-111 Run network building group to intercept every step .. GENERATED FROM PYTHON SOURCE LINES 111-115 .. code-block:: Python n = MyNetwork.from_eddiesobservations(EDDIES_BY_DAYS, window=7) _ = n.group_observations(minimal_area=True) .. GENERATED FROM PYTHON SOURCE LINES 116-133 .. code-block:: Python def update(frame): i_current, i_match, gr = NETWORK_GROUPS[frame] current = EDDIES_BY_DAYS[i_current] x = flatten_line_matrix(current.contour_lon_e) y = flatten_line_matrix(current.contour_lat_e) current_contour.set_data(x, y) match = EDDIES_BY_DAYS[i_match] x = flatten_line_matrix(match.contour_lon_e) y = flatten_line_matrix(match.contour_lat_e) matched_contour.set_data(x, y) groups.set_array(gr) txt.set_text(f"Day {i_current} match with day {i_match}") s = 80 * ones(gr.shape) s[gr == 0] = 4 groups.set_sizes(s) .. GENERATED FROM PYTHON SOURCE LINES 134-136 Anim ---- .. GENERATED FROM PYTHON SOURCE LINES 136-148 .. code-block:: Python fig = plt.figure(figsize=(16, 9), dpi=50) ax = fig.add_axes([0, 0, 1, 1]) ax.set_aspect("equal"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(31, 35.5) cmap = ListedColormap(["gray", *e.COLORS[:-1]], name="from_list", N=30) kw_s = dict(cmap=cmap, vmin=0, vmax=30) groups = ax.scatter(e.lon, e.lat, c=NETWORK_GROUPS[0][2], **kw_s) current_contour = ax.plot([], [], "k", lw=2, label="Current contour")[0] matched_contour = ax.plot([], [], "r", lw=1, ls="--", label="Candidate contour")[0] txt = ax.text(29, 35, "", fontsize=25) ax.legend(fontsize=25) ani = VideoAnimation(fig, update, frames=len(NETWORK_GROUPS), interval=220) .. container:: sphx-glr-animation .. raw:: html .. GENERATED FROM PYTHON SOURCE LINES 149-151 Final Result ------------ .. GENERATED FROM PYTHON SOURCE LINES 151-155 .. code-block:: Python fig = plt.figure(figsize=(16, 9)) ax = fig.add_axes([0, 0, 1, 1]) ax.set_aspect("equal"), ax.grid(), ax.set_xlim(26, 34), ax.set_ylim(31, 35.5) _ = ax.scatter(e.lon, e.lat, c=NETWORK_GROUPS[-1][2], **kw_s) .. image-sg:: /python_module/16_network/images/sphx_glr_pet_group_anim_002.png :alt: pet group anim :srcset: /python_module/16_network/images/sphx_glr_pet_group_anim_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 8.101 seconds) .. _sphx_glr_download_python_module_16_network_pet_group_anim.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: binder-badge .. image:: images/binder_badge_logo.svg :target: https://mybinder.org/v2/gh/AntSimi/py-eddy-tracker/master?urlpath=lab/tree/notebooks/python_module/16_network/pet_group_anim.ipynb :alt: Launch binder :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: pet_group_anim.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: pet_group_anim.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: pet_group_anim.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_