81
81
create_vertice ,
82
82
close_center ,
83
83
get_pixel_in_regular ,
84
+ winding_number_poly ,
84
85
)
85
86
86
87
logger = logging .getLogger ("pet" )
@@ -1497,14 +1498,14 @@ def scatter(self, ax, name=None, ref=None, factor=1, **kwargs):
1497
1498
if ref is not None :
1498
1499
x = (x - ref ) % 360 + ref
1499
1500
kwargs = kwargs .copy ()
1500
- if name is not None and 'c' not in kwargs :
1501
- kwargs ['c' ] = self [name ] * factor
1501
+ if name is not None and "c" not in kwargs :
1502
+ kwargs ["c" ] = self [name ] * factor
1502
1503
return ax .scatter (x , self .latitude , ** kwargs )
1503
1504
1504
1505
def filled (
1505
1506
self ,
1506
1507
ax ,
1507
- varname ,
1508
+ varname = None ,
1508
1509
ref = None ,
1509
1510
intern = False ,
1510
1511
cmap = "magma_r" ,
@@ -1516,7 +1517,7 @@ def filled(
1516
1517
):
1517
1518
"""
1518
1519
:param matplotlib.axes.Axes ax: matplotlib axes use to draw
1519
- :param str,array varname: var which will be use to fill contour, or an array of same size of obs
1520
+ :param str,array varname, None : var which will be use to fill contour, or an array of same size of obs
1520
1521
:param float,None ref: if define use like west bound
1521
1522
:param bool intern: if True draw speed contour instead of effective contour
1522
1523
:param str cmap: matplotlib colormap name
@@ -1529,26 +1530,28 @@ def filled(
1529
1530
1530
1531
.. minigallery:: py_eddy_tracker.EddiesObservations.filled
1531
1532
"""
1532
- cmap = get_cmap (cmap , lut )
1533
1533
x_name , y_name = self .intern (intern )
1534
- v = (self [varname ] if isinstance (varname , str ) else varname ) * factor
1535
1534
x , y = self [x_name ], self [y_name ]
1536
1535
if ref is not None :
1537
1536
# TODO : maybe buggy with global display
1538
1537
shape_out = x .shape
1539
1538
x , y = wrap_longitude (x .reshape (- 1 ), y .reshape (- 1 ), ref )
1540
1539
x , y = x .reshape (shape_out ), y .reshape (shape_out )
1541
- if vmin is None :
1542
- vmin = v .min ()
1543
- if vmax is None :
1544
- vmax = v .max ()
1545
- v = (v - vmin ) / (vmax - vmin )
1546
1540
verts = list ()
1547
- colors = list ()
1548
- for x_ , y_ , v_ in zip (x , y , v ):
1541
+ for x_ , y_ in zip (x , y ):
1549
1542
verts .append (create_vertice (x_ , y_ ))
1550
- colors .append (cmap (v_ ))
1551
- c = PolyCollection (verts , facecolors = colors , ** kwargs )
1543
+ if "facecolors" not in kwargs :
1544
+ kwargs = kwargs .copy ()
1545
+ cmap = get_cmap (cmap , lut )
1546
+ v = (self [varname ] if isinstance (varname , str ) else varname ) * factor
1547
+ if vmin is None :
1548
+ vmin = v .min ()
1549
+ if vmax is None :
1550
+ vmax = v .max ()
1551
+ v = (v - vmin ) / (vmax - vmin )
1552
+ colors = [cmap (v_ ) for v_ in v ]
1553
+ kwargs ["facecolors" ] = colors
1554
+ c = PolyCollection (verts , ** kwargs )
1552
1555
ax .add_collection (c )
1553
1556
c .cmap = cmap
1554
1557
c .norm = Normalize (vmin = vmin , vmax = vmax )
@@ -1627,6 +1630,19 @@ def last_obs(self):
1627
1630
m [:- 1 ][self ["n" ][1 :] == 0 ] = True
1628
1631
return self .extract_with_mask (m )
1629
1632
1633
+ def inside (self , x , y , intern = False ):
1634
+ """
1635
+ True for each postion inside an eddy
1636
+
1637
+ :param array x: longitude
1638
+ :param array y: latitude
1639
+ :param bool intern: If true use speed contour instead of effective contour
1640
+ :return: flag
1641
+ :rtype: array[bool]
1642
+ """
1643
+ xname , yname = self .intern (intern )
1644
+ return insidepoly (x , y , self [xname ], self [yname ])
1645
+
1630
1646
def grid_count (self , bins , intern = False , center = False ):
1631
1647
"""
1632
1648
Compute count of eddies in each bin (use of all pixel in each contour)
@@ -1720,14 +1736,14 @@ def interp_grid(
1720
1736
"""
1721
1737
if method == "center" :
1722
1738
return grid_object .interp (varname , self .longitude , self .latitude )
1723
- elif method in ("min" , "max" , "mean" , ' count' ):
1739
+ elif method in ("min" , "max" , "mean" , " count" ):
1724
1740
x0 = grid_object .x_bounds [0 ]
1725
1741
x_name , y_name = self .intern (False if intern is None else intern )
1726
1742
x_ref = ((self .longitude - x0 ) % 360 + x0 - 180 ).reshape (- 1 , 1 )
1727
1743
x , y = (self [x_name ] - x_ref ) % 360 + x_ref , self [y_name ]
1728
1744
grid = grid_object .grid (varname )
1729
1745
result = empty (self .shape , dtype = grid .dtype if dtype is None else dtype )
1730
- min_method = method == ' min'
1746
+ min_method = method == " min"
1731
1747
grid_stat (
1732
1748
grid_object .x_c ,
1733
1749
grid_object .y_c ,
@@ -1736,7 +1752,7 @@ def interp_grid(
1736
1752
y ,
1737
1753
result ,
1738
1754
grid_object .is_circular (),
1739
- method = ' max' if min_method else method
1755
+ method = " max" if min_method else method ,
1740
1756
)
1741
1757
return - result if min_method else result
1742
1758
else :
@@ -1760,7 +1776,34 @@ def grid_count_(grid, i, j):
1760
1776
1761
1777
1762
1778
@njit (cache = True )
1763
- def grid_stat (x_c , y_c , grid , x , y , result , circular = False , method = 'mean' ):
1779
+ def insidepoly (x_p , y_p , x_c , y_c ):
1780
+ """
1781
+ True for each postion inside an contour
1782
+
1783
+ :param array x_p: longitude to test
1784
+ :param array y_p: latitude to test
1785
+ :param array x_c: longitude of contours
1786
+ :param array y_c: latitude of contours
1787
+ """
1788
+ nb_p = x_p .shape [0 ]
1789
+ nb_c = x_c .shape [0 ]
1790
+ flag = zeros (nb_p , dtype = numba_types .bool_ )
1791
+ for i in range (nb_c ):
1792
+ x_c_min , y_c_min = x_c [i ].min (), y_c [i ].min ()
1793
+ x_c_max , y_c_max = x_c [i ].max (), y_c [i ].max ()
1794
+ v = create_vertice (x_c [i ], y_c [i ])
1795
+ for j in range (nb_p ):
1796
+ x , y = x_p [j ], y_p [j ]
1797
+ if flag [j ]:
1798
+ continue
1799
+ if x > x_c_min and x < x_c_max and y > y_c_min and y < y_c_max :
1800
+ if winding_number_poly (x , y , v ) != 0 :
1801
+ flag [j ] = True
1802
+ return flag
1803
+
1804
+
1805
+ @njit (cache = True )
1806
+ def grid_stat (x_c , y_c , grid , x , y , result , circular = False , method = "mean" ):
1764
1807
"""
1765
1808
Compute mean of grid for each contour
1766
1809
@@ -1777,8 +1820,8 @@ def grid_stat(x_c, y_c, grid, x, y, result, circular=False, method='mean'):
1777
1820
xstep , ystep = x_c [1 ] - x_c [0 ], y_c [1 ] - y_c [0 ]
1778
1821
x0 , y0 = x_c - xstep / 2.0 , y_c - ystep / 2.0
1779
1822
nb_x = x_c .shape [0 ]
1780
- max_method = ' max' == method
1781
- mean_method = ' mean' == method
1823
+ max_method = " max" == method
1824
+ mean_method = " mean" == method
1782
1825
for elt in range (nb ):
1783
1826
v = create_vertice (x [elt ], y [elt ],)
1784
1827
(x_start , x_stop ), (y_start , y_stop ) = bbox_indice_regular (
0 commit comments