159159import csv , warnings , copy , os
160160
161161import numpy as np
162-
162+ ma = np . ma
163163from matplotlib import verbose
164164
165165import matplotlib .nxutils as nxutils
@@ -247,7 +247,7 @@ def _spectral_helper(x, y, NFFT=256, Fs=2, detrend=detrend_none,
247247 #The checks for if y is x are so that we can use the same function to
248248 #implement the core of psd(), csd(), and spectrogram() without doing
249249 #extra calculations. We return the unaveraged Pxy, freqs, and t.
250-
250+
251251 #Make sure we're dealing with a numpy array. If y and x were the same
252252 #object to start with, keep them that way
253253 same_data = y is x
@@ -309,7 +309,7 @@ def _spectral_helper(x, y, NFFT=256, Fs=2, detrend=detrend_none,
309309 Pxy /= (np .abs (windowVals )** 2 ).sum ()
310310 t = 1. / Fs * (ind + NFFT / 2. )
311311 freqs = float (Fs ) / pad_to * np .arange (numFreqs )
312-
312+
313313 return Pxy , freqs , t
314314
315315#Split out these keyword docs so that they can be used elsewhere
@@ -2104,7 +2104,8 @@ def mapped_r2field(name):
21042104
21052105
21062106def csv2rec (fname , comments = '#' , skiprows = 0 , checkrows = 0 , delimiter = ',' ,
2107- converterd = None , names = None , missing = '' , missingd = None ):
2107+ converterd = None , names = None , missing = '' , missingd = None ,
2108+ use_mrecords = True ):
21082109 """
21092110 Load data from comma/space/tab delimited file in *fname* into a
21102111 numpy record array and return the record array.
@@ -2139,9 +2140,11 @@ def csv2rec(fname, comments='#', skiprows=0, checkrows=0, delimiter=',',
21392140 be masked, e.g. '0000-00-00' or 'unused'
21402141
21412142 - *missing*: a string whose value signals a missing field regardless of
2142- the column it appears in, e.g. 'unused'
2143+ the column it appears in
21432144
2144- If no rows are found, *None* is returned -- see :file:`examples/loadrec.py`
2145+ - *use_mrecords*: if True, return an mrecords.fromrecords record array if any of the data are missing
2146+
2147+ If no rows are found, *None* is returned -- see :file:`examples/loadrec.py`
21452148 """
21462149
21472150 if converterd is None :
@@ -2338,7 +2341,8 @@ def get_converters(reader):
23382341
23392342 if not len (rows ):
23402343 return None
2341- if np .any (rowmasks ):
2344+
2345+ if use_mrecords and np .any (rowmasks ):
23422346 try : from numpy .ma import mrecords
23432347 except ImportError :
23442348 raise RuntimeError ('numpy 1.05 or later is required for masked array support' )
@@ -2938,19 +2942,25 @@ def poly_below(xmin, xs, ys):
29382942 xv, yv = poly_below(0, x, y)
29392943 ax.fill(xv, yv)
29402944 """
2941- xs = np .asarray (xs )
2942- ys = np .asarray (ys )
2945+ if ma .isMaskedArray (xs ) or ma .isMaskedArray (ys ):
2946+ nx = ma
2947+ else :
2948+ nx = np
2949+
2950+ xs = nx .asarray (xs )
2951+ ys = nx .asarray (ys )
29432952 Nx = len (xs )
29442953 Ny = len (ys )
29452954 assert (Nx == Ny )
2946- x = xmin * np .ones (2 * Nx )
2947- y = np .ones (2 * Nx )
2955+ x = xmin * nx .ones (2 * Nx )
2956+ y = nx .ones (2 * Nx )
29482957 x [:Nx ] = xs
29492958 y [:Nx ] = ys
29502959 y [Nx :] = ys [::- 1 ]
29512960 return x , y
29522961
29532962
2963+
29542964def poly_between (x , ylower , yupper ):
29552965 """
29562966 Given a sequence of *x*, *ylower* and *yupper*, return the polygon
@@ -2961,17 +2971,23 @@ def poly_between(x, ylower, yupper):
29612971 Return value is *x*, *y* arrays for use with
29622972 :meth:`matplotlib.axes.Axes.fill`.
29632973 """
2974+ if ma .isMaskedArray (ylower ) or ma .isMaskedArray (yupper ) or ma .isMaskedArray (x ):
2975+ nx = ma
2976+ else :
2977+ nx = np
2978+
29642979 Nx = len (x )
29652980 if not cbook .iterable (ylower ):
2966- ylower = ylower * np .ones (Nx )
2981+ ylower = ylower * nx .ones (Nx )
29672982
29682983 if not cbook .iterable (yupper ):
2969- yupper = yupper * np .ones (Nx )
2984+ yupper = yupper * nx .ones (Nx )
29702985
2971- x = np .concatenate ( (x , x [::- 1 ]) )
2972- y = np .concatenate ( (yupper , ylower [::- 1 ]) )
2986+ x = nx .concatenate ( (x , x [::- 1 ]) )
2987+ y = nx .concatenate ( (yupper , ylower [::- 1 ]) )
29732988 return x ,y
29742989
2990+
29752991def is_closed_polygon (X ):
29762992 """
29772993 Tests whether first and last object in a sequence are the same. These are
@@ -2980,6 +2996,28 @@ def is_closed_polygon(X):
29802996 """
29812997 return np .all (X [0 ] == X [- 1 ])
29822998
2999+
3000+ def contiguous_regions (mask ):
3001+ """
3002+ return a list of (ind0, ind1) such that mask[ind0:ind1].all() is
3003+ True and we cover all such regions
3004+
3005+ TODO: this is a pure python implementation which probably has a much faster numpy impl
3006+ """
3007+
3008+ in_region = None
3009+ boundaries = []
3010+ for i , val in enumerate (mask ):
3011+ if in_region is None and val :
3012+ in_region = i
3013+ elif in_region is not None and not val :
3014+ boundaries .append ((in_region , i ))
3015+ in_region = None
3016+
3017+ if in_region is not None :
3018+ boundaries .append ((in_region , i + 1 ))
3019+ return boundaries
3020+
29833021##################################################
29843022# Vector and path length geometry calculations
29853023##################################################
0 commit comments