Skip to content

Commit 0aa8bd9

Browse files
committed
add function to get circle instead of contour
1 parent b54c9b7 commit 0aa8bd9

File tree

6 files changed

+146
-4
lines changed

6 files changed

+146
-4
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""
2+
Display contour & circle
3+
========================
4+
5+
"""
6+
7+
from matplotlib import pyplot as plt
8+
from py_eddy_tracker.observations.observation import EddiesObservations
9+
from py_eddy_tracker import data
10+
11+
# %%
12+
# Load detection files
13+
a = EddiesObservations.load_file(data.get_path("Anticyclonic_20190223.nc"))
14+
15+
# %%
16+
# Plot
17+
fig = plt.figure(figsize=(15, 8))
18+
ax = fig.add_axes((0.05, 0.05, 0.9, 0.9))
19+
ax.set_aspect("equal")
20+
ax.set_xlim(10, 70)
21+
ax.set_ylim(-50, -25)
22+
a.display(ax, label="Anticyclonic contour", color="r", lw=1)
23+
24+
# Replace contour by circle
25+
a.circle_contour()
26+
a.display(ax, label="Anticyclonic circle", color="g", lw=1)
27+
ax.legend(loc="upper right")
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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+
"\nDisplay contour & circle\n========================\n"
19+
]
20+
},
21+
{
22+
"cell_type": "code",
23+
"execution_count": null,
24+
"metadata": {
25+
"collapsed": false
26+
},
27+
"outputs": [],
28+
"source": [
29+
"from matplotlib import pyplot as plt\nfrom py_eddy_tracker.observations.observation import EddiesObservations\nfrom py_eddy_tracker import data"
30+
]
31+
},
32+
{
33+
"cell_type": "markdown",
34+
"metadata": {},
35+
"source": [
36+
"Load detection files\n\n"
37+
]
38+
},
39+
{
40+
"cell_type": "code",
41+
"execution_count": null,
42+
"metadata": {
43+
"collapsed": false
44+
},
45+
"outputs": [],
46+
"source": [
47+
"a = EddiesObservations.load_file(data.get_path(\"Anticyclonic_20190223.nc\"))"
48+
]
49+
},
50+
{
51+
"cell_type": "markdown",
52+
"metadata": {},
53+
"source": [
54+
"Plot\n\n"
55+
]
56+
},
57+
{
58+
"cell_type": "code",
59+
"execution_count": null,
60+
"metadata": {
61+
"collapsed": false
62+
},
63+
"outputs": [],
64+
"source": [
65+
"fig = plt.figure(figsize=(15, 8))\nax = fig.add_axes((0.05, 0.05, 0.9, 0.9))\nax.set_aspect(\"equal\")\nax.set_xlim(10, 70)\nax.set_ylim(-50, -25)\na.display(ax, label=\"Anticyclonic contour\", color=\"r\", lw=1)\n\n# Replace contour by circle\na.circle_contour()\na.display(ax, label=\"Anticyclonic circle\", color=\"g\", lw=1)\nax.legend(loc=\"upper right\")"
66+
]
67+
}
68+
],
69+
"metadata": {
70+
"kernelspec": {
71+
"display_name": "Python 3",
72+
"language": "python",
73+
"name": "python3"
74+
},
75+
"language_info": {
76+
"codemirror_mode": {
77+
"name": "ipython",
78+
"version": 3
79+
},
80+
"file_extension": ".py",
81+
"mimetype": "text/x-python",
82+
"name": "python",
83+
"nbconvert_exporter": "python",
84+
"pygments_lexer": "ipython3",
85+
"version": "3.7.7"
86+
}
87+
},
88+
"nbformat": 4,
89+
"nbformat_minor": 0
90+
}

notebooks/python_module/08_tracking_manipulation/pet_track_anim.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
},
2727
"outputs": [],
2828
"source": [
29-
"from matplotlib import pyplot as plt\nfrom matplotlib.collections import LineCollection\nimport matplotlib.transforms as mt\nfrom numpy import arange\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations\nfrom py_eddy_tracker.poly import create_vertice\nimport py_eddy_tracker_sample"
29+
"from matplotlib import pyplot as plt\nfrom matplotlib.collections import LineCollection\nfrom numpy import arange\nfrom py_eddy_tracker.observations.tracking import TrackEddiesObservations\nfrom py_eddy_tracker.poly import create_vertice\nimport py_eddy_tracker_sample"
3030
]
3131
},
3232
{

notebooks/python_module/10_tracking_diagnostics/pet_center_count.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
},
6363
"outputs": [],
6464
"source": [
65-
"fig = plt.figure(figsize=(12, 18.5))\nax_a = fig.add_axes([0.03, 0.75, 0.90, 0.25])\nax_a.set_title(\"Anticyclonic center frequency\")\nax_c = fig.add_axes([0.03, 0.5, 0.90, 0.25])\nax_c.set_title(\"Cyclonic center frequency\")\nax_all = fig.add_axes([0.03, 0.25, 0.90, 0.25])\nax_all.set_title(\"All eddies center frequency\")\nax_ratio = fig.add_axes([0.03, 0.0, 0.90, 0.25])\nax_ratio.set_title(\"Ratio cyclonic / Anticyclonic\")\n\n# Count pixel used for each center\ng_a = a.grid_count(bins, intern=True, center=True)\nm = g_a.display(ax_a, **kwargs_pcolormesh)\ng_c = c.grid_count(bins, intern=True, center=True)\nm = g_c.display(ax_c, **kwargs_pcolormesh)\n# Compute a ratio Cyclonic / Anticyclonic\nratio = g_c.vars[\"count\"] / g_a.vars[\"count\"]\n\n# Mask manipulation to be able to sum the 2 grids\nm_c = g_c.vars[\"count\"].mask\nm = m_c & g_a.vars[\"count\"].mask\ng_c.vars[\"count\"][m_c] = 0\ng_c.vars[\"count\"] += g_a.vars[\"count\"]\ng_c.vars[\"count\"].mask = m\n\nm = g_c.display(ax_all, **kwargs_pcolormesh)\ncb = plt.colorbar(m, cax=fig.add_axes([0.94, 0.27, 0.01, 0.7]))\ncb.set_label(\"Eddies by 1\u00b0^2 by day\")\n\ng_c.vars[\"count\"] = ratio\nm = g_c.display(ax_ratio, name=\"count\", vmin=0.1, vmax=10, norm=LogNorm())\nplt.colorbar(m, cax=fig.add_axes([0.94, 0.02, 0.01, 0.2]))\n\nfor ax in (ax_a, ax_c, ax_all, ax_ratio):\n ax.set_aspect(\"equal\")\n ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\n ax.grid()"
65+
"fig = plt.figure(figsize=(12, 18.5))\nax_a = fig.add_axes([0.03, 0.75, 0.90, 0.25])\nax_a.set_title(\"Anticyclonic center frequency\")\nax_c = fig.add_axes([0.03, 0.5, 0.90, 0.25])\nax_c.set_title(\"Cyclonic center frequency\")\nax_all = fig.add_axes([0.03, 0.25, 0.90, 0.25])\nax_all.set_title(\"All eddies center frequency\")\nax_ratio = fig.add_axes([0.03, 0.0, 0.90, 0.25])\nax_ratio.set_title(\"Ratio cyclonic / Anticyclonic\")\n\n# Count pixel used for each center\ng_a = a.grid_count(bins, intern=True, center=True)\ng_a.display(ax_a, **kwargs_pcolormesh)\ng_c = c.grid_count(bins, intern=True, center=True)\ng_c.display(ax_c, **kwargs_pcolormesh)\n# Compute a ratio Cyclonic / Anticyclonic\nratio = g_c.vars[\"count\"] / g_a.vars[\"count\"]\n\n# Mask manipulation to be able to sum the 2 grids\nm_c = g_c.vars[\"count\"].mask\nm = m_c & g_a.vars[\"count\"].mask\ng_c.vars[\"count\"][m_c] = 0\ng_c.vars[\"count\"] += g_a.vars[\"count\"]\ng_c.vars[\"count\"].mask = m\n\nm = g_c.display(ax_all, **kwargs_pcolormesh)\ncb = plt.colorbar(m, cax=fig.add_axes([0.94, 0.27, 0.01, 0.7]))\ncb.set_label(\"Eddies by 1\u00b0^2 by day\")\n\ng_c.vars[\"count\"] = ratio\nm = g_c.display(ax_ratio, name=\"count\", vmin=0.1, vmax=10, norm=LogNorm())\nplt.colorbar(m, cax=fig.add_axes([0.94, 0.02, 0.01, 0.2]))\n\nfor ax in (ax_a, ax_c, ax_all, ax_ratio):\n ax.set_aspect(\"equal\")\n ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\n ax.grid()"
6666
]
6767
}
6868
],

notebooks/python_module/10_tracking_diagnostics/pet_pixel_used.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
},
6363
"outputs": [],
6464
"source": [
65-
"fig = plt.figure(figsize=(12, 18.5))\nax_a = fig.add_axes([0.03, 0.75, 0.90, 0.25])\nax_a.set_title(\"Anticyclonic frequency\")\nax_c = fig.add_axes([0.03, 0.5, 0.90, 0.25])\nax_c.set_title(\"Cyclonic frequency\")\nax_all = fig.add_axes([0.03, 0.25, 0.90, 0.25])\nax_all.set_title(\"All eddies frequency\")\nax_ratio = fig.add_axes([0.03, 0.0, 0.90, 0.25])\nax_ratio.set_title(\"Ratio cyclonic / Anticyclonic\")\n\n# Count pixel used for each contour\ng_a = a.grid_count(bins, intern=True)\nm = g_a.display(ax_a, **kwargs_pcolormesh)\ng_c = c.grid_count(bins, intern=True)\nm = g_c.display(ax_c, **kwargs_pcolormesh)\n# Compute a ratio Cyclonic / Anticyclonic\nratio = g_c.vars[\"count\"] / g_a.vars[\"count\"]\n\n# Mask manipulation to be able to sum the 2 grids\nm_c = g_c.vars[\"count\"].mask\nm = m_c & g_a.vars[\"count\"].mask\ng_c.vars[\"count\"][m_c] = 0\ng_c.vars[\"count\"] += g_a.vars[\"count\"]\ng_c.vars[\"count\"].mask = m\n\nm = g_c.display(ax_all, **kwargs_pcolormesh)\nplt.colorbar(m, cax=fig.add_axes([0.95, 0.27, 0.01, 0.7]))\n\ng_c.vars[\"count\"] = ratio\nm = g_c.display(ax_ratio, name=\"count\", vmin=0.1, vmax=10, norm=LogNorm())\nplt.colorbar(m, cax=fig.add_axes([0.95, 0.02, 0.01, 0.2]))\n\nfor ax in (ax_a, ax_c, ax_all, ax_ratio):\n ax.set_aspect(\"equal\")\n ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\n ax.grid()"
65+
"fig = plt.figure(figsize=(12, 18.5))\nax_a = fig.add_axes([0.03, 0.75, 0.90, 0.25])\nax_a.set_title(\"Anticyclonic frequency\")\nax_c = fig.add_axes([0.03, 0.5, 0.90, 0.25])\nax_c.set_title(\"Cyclonic frequency\")\nax_all = fig.add_axes([0.03, 0.25, 0.90, 0.25])\nax_all.set_title(\"All eddies frequency\")\nax_ratio = fig.add_axes([0.03, 0.0, 0.90, 0.25])\nax_ratio.set_title(\"Ratio cyclonic / Anticyclonic\")\n\n# Count pixel used for each contour\ng_a = a.grid_count(bins, intern=True)\ng_a.display(ax_a, **kwargs_pcolormesh)\ng_c = c.grid_count(bins, intern=True)\ng_c.display(ax_c, **kwargs_pcolormesh)\n# Compute a ratio Cyclonic / Anticyclonic\nratio = g_c.vars[\"count\"] / g_a.vars[\"count\"]\n\n# Mask manipulation to be able to sum the 2 grids\nm_c = g_c.vars[\"count\"].mask\nm = m_c & g_a.vars[\"count\"].mask\ng_c.vars[\"count\"][m_c] = 0\ng_c.vars[\"count\"] += g_a.vars[\"count\"]\ng_c.vars[\"count\"].mask = m\n\nm = g_c.display(ax_all, **kwargs_pcolormesh)\nplt.colorbar(m, cax=fig.add_axes([0.95, 0.27, 0.01, 0.7]))\n\ng_c.vars[\"count\"] = ratio\nm = g_c.display(ax_ratio, name=\"count\", vmin=0.1, vmax=10, norm=LogNorm())\nplt.colorbar(m, cax=fig.add_axes([0.95, 0.02, 0.01, 0.2]))\n\nfor ax in (ax_a, ax_c, ax_all, ax_ratio):\n ax.set_aspect(\"equal\")\n ax.set_xlim(-6, 36.5), ax.set_ylim(30, 46)\n ax.grid()"
6666
]
6767
}
6868
],

src/py_eddy_tracker/observations/observation.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
ceil,
4949
arange,
5050
histogram2d,
51+
linspace,
52+
sin,
5153
)
5254
from netCDF4 import Dataset
5355
from datetime import datetime
@@ -58,7 +60,13 @@
5860
from tokenize import TokenError
5961
from matplotlib.path import Path as BasePath
6062
from .. import VAR_DESCR, VAR_DESCR_inv
61-
from ..generic import distance_grid, distance, flatten_line_matrix, wrap_longitude
63+
from ..generic import (
64+
distance_grid,
65+
distance,
66+
flatten_line_matrix,
67+
wrap_longitude,
68+
local_to_coordinates,
69+
)
6270
from ..poly import bbox_intersection, common_area, create_vertice
6371

6472
logger = logging.getLogger("pet")
@@ -247,6 +255,23 @@ def add_rotation_type(self):
247255
new.observations["type_cyc"] = self.sign_type
248256
return new
249257

258+
def circle_contour(self):
259+
angle = radians(linspace(0, 360, self.track_array_variables))
260+
x_norm, y_norm = cos(angle), sin(angle)
261+
for i, obs in enumerate(self):
262+
r_s, r_e, x, y = (
263+
obs["radius_s"],
264+
obs["radius_e"],
265+
obs["lon"],
266+
obs["lat"],
267+
)
268+
obs["contour_lon_s"], obs["contour_lat_s"] = local_to_coordinates(
269+
x_norm * r_s, y_norm * r_s, x, y
270+
)
271+
obs["contour_lon_e"], obs["contour_lat_e"] = local_to_coordinates(
272+
x_norm * r_e, y_norm * r_e, x, y
273+
)
274+
250275
@property
251276
def dtype(self):
252277
"""Return dtype to build numpy array

0 commit comments

Comments
 (0)