def set_data(self, x, y, A): x = asarray(x).astype(Float32) y = asarray(y).astype(Float32) A = asarray(A) if len(x.shape) != 1 or len(y.shape) != 1\ or A.shape[0:2] != (y.shape[0], x.shape[0]): raise TypeError("Axes don't match array shape") if len(A.shape) not in [2, 3]: raise TypeError("Can only plot 2D or 3D data") if len(A.shape) == 3 and A.shape[2] not in [1, 3, 4]: raise TypeError("3D arrays must have three (RGB) or four (RGBA) color components") if len(A.shape) == 3 and A.shape[2] == 1: A.shape = A.shape[0:2] if len(A.shape) == 2: if typecode(A) != UInt8: A = (self.cmap(self.norm(A))*255).astype(UInt8) else: A = repeat(A[:,:,NewAxis], 4, 2) A[:,:,3] = 255 else: if typecode(A) != UInt8: A = (255*A).astype(UInt8) if A.shape[2] == 3: B = zeros(tuple(list(A.shape[0:2]) + [4]), UInt8) B[:,:,0:3] = A B[:,:,3] = 255 A = B self._A = A self._Ax = x self._Ay = y self._imcache = None
def dist_point_to_segment(p, s0, s1): """ get the distance of a point to a segment. p, s0, s1 are xy sequences This algorithm from http://softsurfer.com/Archive/algorithm_0102/algorithm_0102.htm#Distance%20to%20Ray%20or%20Segment """ p = asarray(p, Float) s0 = asarray(s0, Float) s1 = asarray(s1, Float) v = s1 - s0 w = p - s0 c1 = dot(w,v); if ( c1 <= 0 ): return dist(p, s0); c2 = dot(v,v) if ( c2 <= c1 ): return dist(p, s1); b = c1 / c2 pb = s0 + b * v; return dist(p, pb)
def set_data(self, *args): """ Set the x and y data ACCEPTS: (array xdata, array ydata) """ if len(args)==1: x, y = args[0] else: x, y = args try: del self._xc, self._yc except AttributeError: pass self._x = asarray(x, Float) self._y = asarray(y, Float) if len(self._x.shape)>1: self._x = ravel(self._x) if len(self._y.shape)>1: self._y = ravel(self._y) if len(self._y)==1 and len(self._x)>1: self._y = self._y*ones(self._x.shape, Float) if len(self._x) != len(self._y): raise RuntimeError('xdata and ydata must be the same length') if self._useDataClipping: self._xsorted = self._is_sorted(self._x) self._logcache = None
def _update_x_y_logcache(self): # check cache need_update = False try: for key, var_id in self._cache_inputs.iteritems(): if id(getattr(self, key)) != var_id: need_update = True break except: need_update = True if not need_update: return # update cache for key in self._cache_inputs.keys(): try: self._cache_inputs[key] = id(getattr(self, key)) except: pass # make sure that result values exist and release # previous values self._cached__x = None self._cached__y = None self._cached__segments = None self._cached__logcache = None if self.is_unitsmgr_set(): unitsmgr = self.get_unitsmgr() x, y = unitsmgr._convert_units((self._x_orig, self._xunits), (self._y_orig, self._yunits)) else: x, y = (self._x_orig, self._y_orig) x = ma.ravel(x) y = ma.ravel(y) if len(x) == 1 and len(y) > 1: x = x * ones(y.shape, Float) if len(y) == 1 and len(x) > 1: y = y * ones(x.shape, Float) if len(x) != len(y): raise RuntimeError("xdata and ydata must be the same length") mx = ma.getmask(x) my = ma.getmask(y) mask = ma.mask_or(mx, my) if mask is not ma.nomask: x = ma.masked_array(x, mask=mask).compressed() y = ma.masked_array(y, mask=mask).compressed() self._cached__segments = unmasked_index_ranges(mask) else: self._cached__segments = None self._cached__x = asarray(x, Float) self._cached__y = asarray(y, Float) self._cached__logcache = None
def rk4(derivs, y0, t): """ Integrate 1D or ND system of ODEs from initial state y0 at sample times t. derivs returns the derivative of the system and has the signature dy = derivs(yi, ti) Example 1 : ## 2D system # Numeric solution def derivs6(x,t): d1 = x[0] + 2*x[1] d2 = -3*x[0] + 4*x[1] return (d1, d2) dt = 0.0005 t = arange(0.0, 2.0, dt) y0 = (1,2) yout = rk4(derivs6, y0, t) Example 2: ## 1D system alpha = 2 def derivs(x,t): return -alpha*x + exp(-t) y0 = 1 yout = rk4(derivs, y0, t) """ try: Ny = len(y0) except TypeError: yout = zeros( (len(t),), Float) else: yout = zeros( (len(t), Ny), Float) yout[0] = y0 i = 0 for i in arange(len(t)-1): thist = t[i] dt = t[i+1] - thist dt2 = dt/2.0 y0 = yout[i] k1 = asarray(derivs(y0, thist)) k2 = asarray(derivs(y0 + dt2*k1, thist+dt2)) k3 = asarray(derivs(y0 + dt2*k2, thist+dt2)) k4 = asarray(derivs(y0 + dt*k3, thist+dt)) yout[i+1] = y0 + dt/6.0*(k1 + 2*k2 + 2*k3 + k4) return yout
def draw_regpoly_collection( self, clipbox, offsets, transOffset, verts, sizes, facecolors, edgecolors, linewidths, antialiaseds): """ Draw a regular poly collection offsets - is a sequence is x,y tuples transOffset - maps this to display coords verts - are the vertices of the regular polygon at the origin sizes are the area of the circle that circumscribes the polygon in points^2 facecolors and edgecolors are a sequence of RGBA tuples linewidths are a sequence of linewidths antialiaseds are a sequence of 0,1 integers whether to use aa """ gc = self.new_gc() if clipbox is not None: gc.set_clip_rectangle(clipbox.get_bounds()) xverts, yverts = zip(*verts) xverts = asarray(xverts) yverts = asarray(yverts) Nface = len(facecolors) Nedge = len(edgecolors) Nlw = len(linewidths) Naa = len(antialiaseds) Nsizes = len(sizes) for i, loc in enumerate(offsets): xo,yo = transOffset.xy_tup(loc) #print 'xo, yo', loc, (xo, yo) scale = sizes[i % Nsizes] thisxverts = scale*xverts + xo thisyverts = scale*yverts + yo #print 'xverts', xverts rf,gf,bf,af = facecolors[i % Nface] re,ge,be,ae = edgecolors[i % Nedge] if af==0: rgbFace = None else: rgbFace = rf,gf,bf # the draw_poly interface can't handle separate alphas for # edge and face so we'll just use alpha = max(af,ae) gc.set_foreground( (re,ge,be), isRGB=True) gc.set_alpha( alpha ) gc.set_linewidth( linewidths[i % Nlw] ) gc.set_antialiased( antialiaseds[i % Naa] ) #print 'verts', zip(thisxverts, thisyverts) self.draw_polygon(gc, rgbFace, zip(thisxverts, thisyverts))
def set_data(self, *args): """ Set the x and y data ACCEPTS: (array xdata, array ydata) """ if len(args) == 1: x, y = args[0] else: x, y = args try: del self._xc, self._yc except AttributeError: pass self._masked_x = None self._masked_y = None mx = ma.getmask(x) my = ma.getmask(y) if mx is not None: mx = ravel(mx) self._masked_x = x if my is not None: my = ravel(my) self._masked_y = y mask = ma.mask_or(mx, my) if mask is not None: x = ma.masked_array(ma.ravel(x), mask=mask).compressed() y = ma.masked_array(ma.ravel(y), mask=mask).compressed() self._segments = unmasked_index_ranges(mask) else: self._segments = None self._x = asarray(x, Float) self._y = asarray(y, Float) if len(self._x.shape) > 1: self._x = ravel(self._x) if len(self._y.shape) > 1: self._y = ravel(self._y) # What is the rationale for the following two lines? # And why is there not a similar pair with _x and _y reversed? if len(self._y) == 1 and len(self._x) > 1: self._y = self._y * ones(self._x.shape, Float) if len(self._x) != len(self._y): raise RuntimeError("xdata and ydata must be the same length") if self._useDataClipping: self._xsorted = self._is_sorted(self._x) self._logcache = None
def set_data(self, *args): """ Set the x and y data ACCEPTS: (array xdata, array ydata) """ if len(args)==1: x, y = args[0] else: x, y = args self._x_orig = x self._y_orig = y if (self._xunits and hasattr(x, 'convert_to')): x = x.convert_to(self._xunits).get_value() if (hasattr(x, 'get_value')): x = x.get_value() if (self._yunits and hasattr(y, 'convert_to')): y = y.convert_to(self._yunits).get_value() if (hasattr(y, 'get_value')): y = y.get_value() x = ma.ravel(x) y = ma.ravel(y) if len(x)==1 and len(y)>1: x = x * ones(y.shape, Float) if len(y)==1 and len(x)>1: y = y * ones(x.shape, Float) if len(x) != len(y): raise RuntimeError('xdata and ydata must be the same length') mx = ma.getmask(x) my = ma.getmask(y) mask = ma.mask_or(mx, my) if mask is not ma.nomask: x = ma.masked_array(x, mask=mask).compressed() y = ma.masked_array(y, mask=mask).compressed() self._segments = unmasked_index_ranges(mask) else: self._segments = None self._x = asarray(x, Float) self._y = asarray(y, Float) self._logcache = None
def epoch2num(e): """ convert an epoch or sequence of epochs to the new date format, days since 0001 """ spd = 24.*3600. return 719163 + asarray(e)/spd
def _contour_args(self, filled, badmask, origin, extent, *args): if filled: fn = 'contourf' else: fn = 'contour' Nargs = len(args) if Nargs <= 2: z = args[0] x, y = self._initialize_x_y(z, origin, extent) elif Nargs <=4: x,y,z = self._check_xyz(args[:3]) else: raise TypeError("Too many arguments to %s; see help(%s)" % (fn,fn)) z = asarray(z) # Convert to native array format if necessary. if Nargs == 1 or Nargs == 3: lev = self._autolev(z, 7, filled, badmask) else: # 2 or 4 args level_arg = args[-1] if type(level_arg) == int: lev = self._autolev(z, level_arg, filled, badmask) elif iterable(level_arg) and len(shape(level_arg)) == 1: lev = array([float(fl) for fl in level_arg]) else: raise TypeError("Last %s arg must give levels; see help(%s)" % (fn,fn)) rx = ravel(x) ry = ravel(y) self.ax.set_xlim((min(rx), max(rx))) self.ax.set_ylim((min(ry), max(ry))) return (x, y, z, lev)
def __call__(self, value): vmin = self.vmin vmax = self.vmax if type(value) in [IntType, FloatType]: vtype = 'scalar' val = array([value]) else: vtype = 'array' val = asarray(value) # if both vmin is None and vmax is None, we'll automatically # norm the data to vmin/vmax of the actual data, so the # clipping step won't be needed. if vmin is None and vmax is None: needs_clipping = False else: needs_clipping = True if vmin is None or vmax is None: rval = ravel(val) if vmin is None: vmin = amin(rval) if vmax is None: vmax = amax(rval) if vmin > vmax: raise ValueError("minvalue must be less than or equal to maxvalue") elif vmin==vmax: return 0.*value else: if needs_clipping: val = clip(val,vmin, vmax) result = (1.0/(vmax-vmin))*(val-vmin) if vtype == 'scalar': result = result[0] return result
def __init__(self, dpi, numsides, rotation = 0 , sizes = (1,), **kwargs): """ Draw a regular polygon with numsides. sizes gives the area of the circle circumscribing the regular polygon and rotation is the rotation of the polygon in radians. offsets are a sequence of x,y tuples that give the centers of the polygon in data coordinates, and transOffset is the Transformation instance used to transform the centers onto the canvas. dpi is the figure dpi instance, and is required to do the area scaling. """ PatchCollection.__init__(self,**kwargs) self._sizes = asarray(sizes) self._dpi = dpi r = 1.0/math.sqrt(math.pi) # unit area theta = (2*math.pi/numsides)*arange(numsides) + rotation self._verts = zip( r*sin(theta), r*cos(theta) )
def hist(y, bins=10, normed=0): """ Return the histogram of y with bins equally sized bins. If bins is an array, use the bins. Return value is (n,x) where n is the count for each bin in x If normed is False, return the counts in the first element of the return tuple. If normed is True, return the probability density n/(len(y)*dbin) If y has rank>1, it will be raveled Credits: the Numeric 22 documentation """ y = asarray(y) if len(y.shape)>1: y = ravel(y) if not iterable(bins): ymin, ymax = min(y), max(y) if ymin==ymax: ymin -= 0.5 ymax += 0.5 bins = linspace(ymin, ymax, bins) n = searchsorted(sort(y), bins) n = diff(concatenate([n, [len(y)]])) if normed: db = bins[1]-bins[0] return 1/(len(y)*db)*n, bins else: return n, bins
def __call__(self, value): vmin = self.vmin vmax = self.vmax if type(value) in [IntType, FloatType]: vtype = "scalar" val = array([value]) else: vtype = "array" val = asarray(value) if vmin is None or vmax is None: rval = ravel(val) if vmin is None: vmin = amin(rval) if vmax is None: vmax = amax(rval) if vmin > vmax: raise ValueError("minvalue must be less than or equal to maxvalue") elif vmin == vmax: return 0.0 * value else: val = where(val < vmin, vmin, val) val = where(val > vmax, vmax, val) result = (1.0 / (vmax - vmin)) * (val - vmin) if vtype == "scalar": result = result[0] return result
def longest_ones(x): """ return the indicies of the longest stretch of contiguous ones in x, assuming x is a vector of zeros and ones. If there are two equally long stretches, pick the first """ x = asarray(x) if len(x)==0: return array([]) #print 'x', x ind = find(x==0) if len(ind)==0: return arange(len(x)) if len(ind)==len(x): return array([]) y = zeros( (len(x)+2,), Int) y[1:-1] = x d = diff(y) #print 'd', d up = find(d == 1); dn = find(d == -1); #print 'dn', dn, 'up', up, ind = find( dn-up == max(dn - up)) # pick the first if iterable(ind): ind = ind[0] ind = arange(up[ind], dn[ind]) return ind
def rem(x,y): """ Remainder after division. rem(x,y) is equivalent to x - y.*fix(x./y) in case y is not zero. By convention, rem(x,0) returns None. We keep the convention by Matlab: "The input x and y must be real arrays of the same size, or real scalars." """ x,y = asarray(x),asarray(y) if numerix.shape(x) == numerix.shape(y) or numerix.shape(y) == (): try: return x - y * fix(x/y) except OverflowError: return None raise RuntimeError('Dimension error')
def __call__(self, X, alpha=1.0): """ X is either a scalar or an array (of any dimension). If scalar, a tuple of rgba values is returned, otherwise an array with the new shape = oldshape+(4,). Any values that are outside the 0,1 interval are clipped to that interval before generating rgb values. Alpha must be a scalar """ if not self._isinit: self._init() alpha = min(alpha, 1.0) # alpha must be between 0 and 1 alpha = max(alpha, 0.0) if type(X) in [IntType, FloatType]: vtype = "scalar" xa = array([X]) else: vtype = "array" xa = asarray(X) # assume the data is properly normalized # xa = where(xa>1.,1.,xa) # xa = where(xa<0.,0.,xa) xa = (xa * (self.N - 1)).astype(Int) rgba = zeros(xa.shape + (4,), Float) rgba[..., 0] = take(self._red_lut, xa) rgba[..., 1] = take(self._green_lut, xa) rgba[..., 2] = take(self._blue_lut, xa) rgba[..., 3] = alpha if vtype == "scalar": rgba = tuple(rgba[0, :]) return rgba
def intwave(wavelet, precision=8): """ intwave(wavelet, precision=8) -> [int_psi, x] - for orthogonal wavelets intwave(wavelet, precision=8) -> [int_psi_d, int_psi_r, x] - for other wavelets intwave((function_approx, x), precision=8) -> [int_function, x] - for (function approx., x grid) pair Integrate *psi* wavelet function from -Inf to x using the rectangle integration method. wavelet - Wavelet to integrate (Wavelet object, wavelet name string or (wavelet function approx., x grid) pair) precision = 8 - Precision that will be used for wavelet function approximation computed with the wavefun(level=precision) Wavelet's method. (function_approx, x) - Function to integrate on the x grid. Used instead of Wavelet object to allow custom wavelet functions. """ if isinstance(wavelet, tuple): psi, x = asarray(wavelet[0]), asarray(wavelet[1]) step = x[1] - x[0] return integrate(psi, step), x else: if not isinstance(wavelet, WAVELET_CLASSES): wavelet = wavelet_for_name(wavelet) functions_approximations = wavelet.wavefun(precision) if len(functions_approximations) == 2: # continuous wavelet psi, x = functions_approximations step = x[1] - x[0] return integrate(psi, step), x elif len(functions_approximations) == 3: # orthogonal wavelet phi, psi, x = functions_approximations step = x[1] - x[0] return integrate(psi, step), x else: # biorthogonal wavelet phi_d, psi_d, phi_r, psi_r, x = functions_approximations step = x[1] - x[0] return integrate(psi_d, step), integrate(psi_r, step), x
def set_data(self, *args): """ Set the x and y data ACCEPTS: (array xdata, array ydata) """ if len(args) == 1: x, y = args[0] else: x, y = args try: del self._xc, self._yc except AttributeError: pass self._x_orig = x self._y_orig = y x = ma.ravel(x) y = ma.ravel(y) if len(x) == 1 and len(y) > 1: x = x * ones(y.shape, Float) if len(y) == 1 and len(x) > 1: y = y * ones(x.shape, Float) if len(x) != len(y): raise RuntimeError("xdata and ydata must be the same length") mx = ma.getmask(x) my = ma.getmask(y) mask = ma.mask_or(mx, my) if mask is not None: x = ma.masked_array(x, mask=mask).compressed() y = ma.masked_array(y, mask=mask).compressed() self._segments = unmasked_index_ranges(mask) else: self._segments = None self._x = asarray(x, Float) self._y = asarray(y, Float) if self._useDataClipping: self._xsorted = self._is_sorted(self._x) self._logcache = None
def scanner(s): """ Split a string into mathtext and non-mathtext parts. mathtext is surrounded by $ symbols. quoted \$ are ignored All slash quotes dollar signs are ignored The number of unquoted dollar signs must be even Return value is a list of (substring, inmath) tuples """ if not len(s): return [(s, False)] #print 'testing', s, type(s) inddollar = nonzero(asarray(equal(s,'$'))) quoted = dict([ (ind,1) for ind in nonzero(asarray(equal(s,'\\')))]) indkeep = [ind for ind in inddollar if not quoted.has_key(ind-1)] if len(indkeep)==0: return [(s, False)] if len(indkeep)%2: raise ValueError('Illegal string "%s" (must have balanced dollar signs)'%s) Ns = len(s) indkeep = [ind for ind in indkeep] # make sure we start with the first element if indkeep[0]!=0: indkeep.insert(0,0) # and end with one past the end of the string indkeep.append(Ns+1) Nkeep = len(indkeep) results = [] inmath = s[0] == '$' for i in range(Nkeep-1): i0, i1 = indkeep[i], indkeep[i+1] if not inmath: if i0>0: i0 +=1 else: i1 += 1 if i0>=Ns: break results.append((s[i0:i1], inmath)) inmath = not inmath return results
def locate_label(self, linecontour, labelwidth): """find a good place to plot a label (relatively flat part of the contour) and the angle of rotation for the text object """ nsize= len(linecontour) if labelwidth > 1: xsize = int(ceil(nsize/labelwidth)) else: xsize = 1 if xsize == 1: ysize = nsize else: ysize = labelwidth XX = resize(asarray(linecontour)[:,0],(xsize, ysize)) YY = resize(asarray(linecontour)[:,1],(xsize,ysize)) yfirst = YY[:,0] ylast = YY[:,-1] xfirst = XX[:,0] xlast = XX[:,-1] s = ( (reshape(yfirst, (xsize,1))-YY) * (reshape(xlast,(xsize,1)) - reshape(xfirst,(xsize,1))) - (reshape(xfirst,(xsize,1))-XX) * (reshape(ylast,(xsize,1)) - reshape(yfirst,(xsize,1))) ) L=sqrt((xlast-xfirst)**2+(ylast-yfirst)**2) dist = add.reduce(([(abs(s)[i]/L[i]) for i in range(xsize)]),-1) x,y,ind = self.get_label_coords(dist, XX, YY, ysize, labelwidth) #print 'ind, x, y', ind, x, y angle = arctan2(ylast - yfirst, xlast - xfirst) rotation = angle[ind]*180/pi if rotation > 90: rotation = rotation -180 if rotation < -90: rotation = 180 + rotation # There must be a more efficient way... lc = [tuple(l) for l in linecontour] dind = lc.index((x,y)) #print 'dind', dind #dind = list(linecontour).index((x,y)) return x,y, rotation, dind
def polyfit(x,y,N): """ Do a best fit polynomial of order N of y to x. Return value is a vector of polynomial coefficients [pk ... p1 p0]. Eg, for N=2 p2*x0^2 + p1*x0 + p0 = y1 p2*x1^2 + p1*x1 + p0 = y1 p2*x2^2 + p1*x2 + p0 = y2 ..... p2*xk^2 + p1*xk + p0 = yk Method: if X is a the Vandermonde Matrix computed from x (see http://mathworld.wolfram.com/VandermondeMatrix.html), then the polynomial least squares solution is given by the 'p' in X*p = y where X is a len(x) x N+1 matrix, p is a N+1 length vector, and y is a len(x) x 1 vector This equation can be solved as p = (XT*X)^-1 * XT * y where XT is the transpose of X and -1 denotes the inverse. For more info, see http://mathworld.wolfram.com/LeastSquaresFittingPolynomial.html, but note that the k's and n's in the superscripts and subscripts on that page. The linear algebra is correct, however. See also polyval """ x = asarray(x)+0. y = asarray(y)+0. y = reshape(y, (len(y),1)) X = Matrix(vander(x, N+1)) Xt = Matrix(transpose(X)) c = array(linear_algebra.inverse(Xt*X)*Xt*y) # convert back to array c.shape = (N+1,) return c
def _contour_args(self, *args): if self.filled: fn = 'contourf' else: fn = 'contour' Nargs = len(args) if Nargs <= 2: z = args[0] x, y = self._initialize_x_y(z) elif Nargs <=4: x,y,z = self._check_xyz(args[:3]) else: raise TypeError("Too many arguments to %s; see help(%s)" % (fn,fn)) z = ma.asarray(z) # Convert to native masked array format if necessary. self.zmax = ma.maximum(z) self.zmin = ma.minimum(z) self._auto = False if self.levels is None: if Nargs == 1 or Nargs == 3: lev = self._autolev(z, 7) else: # 2 or 4 args level_arg = args[-1] if type(level_arg) == int: lev = self._autolev(z, level_arg) elif iterable(level_arg) and len(shape(level_arg)) == 1: lev = array([float(fl) for fl in level_arg]) else: raise TypeError("Last %s arg must give levels; see help(%s)" % (fn,fn)) if self.filled and len(lev) < 2: raise ValueError("Filled contours require at least 2 levels.") # Workaround for cntr.c bug wrt masked interior regions: #if filled: # z = ma.masked_array(z.filled(-1e38)) # It's not clear this is any better than the original bug. self.levels = lev #if self._auto and self.extend in ('both', 'min', 'max'): # raise TypeError("Auto level selection is inconsistent " # + "with use of 'extend' kwarg") self._levels = list(self.levels) if self.extend in ('both', 'min'): self._levels.insert(0, self.zmin - 1) if self.extend in ('both', 'max'): self._levels.append(self.zmax + 1) self._levels = asarray(self._levels) self.vmin = amin(self.levels) # alternative would be self.layers self.vmax = amax(self.levels) if self.extend in ('both', 'min') or self.clip_ends: self.vmin = 2 * self.levels[0] - self.levels[1] if self.extend in ('both', 'max') or self.clip_ends: self.vmax = 2 * self.levels[-1] - self.levels[-2] self.layers = self._levels # contour: a line is a thin layer if self.filled: self.layers = 0.5 * (self._levels[:-1] + self._levels[1:]) if self.extend in ('both', 'min') or self.clip_ends: self.layers[0] = 0.5 * (self.vmin + self._levels[1]) if self.extend in ('both', 'max') or self.clip_ends: self.layers[-1] = 0.5 * (self.vmax + self._levels[-2]) return (x, y, z)
def set_data(self, x, y): try: del self._xc, self._yc except AttributeError: pass self._x = asarray(x, Float) self._y = asarray(y, Float) if len(self._x.shape)>1: self._x = ravel(self._x) if len(self._y.shape)>1: self._y = ravel(self._y) if len(self._y)==1 and len(self._x)>1: self._y = self._y*ones(self._x.shape, Float) if len(self._x) != len(self._y): raise RuntimeError('xdata and ydata must be the same length') if self._useDataClipping: self._xsorted = self._is_sorted(self._x)
def date2num(d): """ d is either a datetime instance or a sequence of datetimes return value is a floating point number (or sequence of floats) which gives number of days (fraction part represents hours, minutes, seconds) since 0001-01-01 00:00:00 UTC """ if not iterable(d): return _to_ordinalf(d) else: return asarray([_to_ordinalf(val) for val in d])
def centfrq(wavelet, precision=8): """ centfrq(wavelet, precision=8) -> float - for orthogonal wavelets centfrq((function_approx, x), precision=8) -> float - for (function approx., x grid) pair Computes the central frequency of the *psi* wavelet function. wavelet - Wavelet (Wavelet object, wavelet name string or (wavelet function approx., x grid) pair) precision = 8 - Precision that will be used for wavelet function approximation computed with the wavefun(level=precision) Wavelet's method. (function_approx, xgrid) - Function defined on xgrid. Used instead of Wavelet object to allow custom wavelet functions. """ if isinstance(wavelet, tuple): psi, x = asarray(wavelet[0]), asarray(wavelet[1]) else: if not isinstance(wavelet, WAVELET_CLASSES): wavelet = wavelet_for_name(wavelet) functions_approximations = wavelet.wavefun(precision) if len(functions_approximations) == 2: psi, x = functions_approximations else: # (psi, x) for (phi, psi, x) # (psi_d, x) for (phi_d, psi_d, phi_r, psi_r, x) psi, x = functions_approximations[1], functions_approximations[-1] domain = float(x[-1] - x[0]) assert domain > 0 index = argmax(abs(fft(psi)[1:])) + 2 if index > len(psi) / 2: index = len(psi) - index + 2 return 1.0 / (domain / (index - 1))
def orthfilt(scaling_filter): assert len(scaling_filter) % 2 == 0 scaling_filter = asarray(scaling_filter, dtype=float64) rec_lo = sqrt(2) * scaling_filter / sum(scaling_filter) dec_lo = rec_lo[::-1] rec_hi = qmf(rec_lo) dec_hi = rec_hi[::-1] return (dec_lo, dec_hi, rec_lo, rec_hi)
def specgram(x, NFFT=256, Fs=2, detrend=detrend_none, window=window_hanning, noverlap=128): """ Compute a spectrogram of data in x. Data are split into NFFT length segements and the PSD of each section is computed. The windowing function window is applied to each segment, and the amount of overlap of each segment is specified with noverlap See pdf for more info. The returned times are the midpoints of the intervals over which the ffts are calculated """ x = asarray(x) assert(NFFT>noverlap) if log(NFFT)/log(2) != int(log(NFFT)/log(2)): raise ValueError, 'NFFT must be a power of 2' # zero pad x up to NFFT if it is shorter than NFFT if len(x)<NFFT: n = len(x) x = resize(x, (NFFT,)) x[n:] = 0 # for real x, ignore the negative frequencies if typecode(x)==Complex: numFreqs=NFFT else: numFreqs = NFFT//2+1 windowVals = window(ones((NFFT,),typecode(x))) step = NFFT-noverlap ind = arange(0,len(x)-NFFT+1,step) n = len(ind) Pxx = zeros((numFreqs,n), Float) # do the ffts of the slices for i in range(n): thisX = x[ind[i]:ind[i]+NFFT] thisX = windowVals*detrend(thisX) fx = absolute(fft(thisX))**2 # Scale the spectrum by the norm of the window to compensate for # windowing loss; see Bendat & Piersol Sec 11.5.2 Pxx[:,i] = divide(fx[:numFreqs], norm(windowVals)**2) t = 1/Fs*(ind+NFFT/2) freqs = Fs/NFFT*arange(numFreqs) return Pxx, freqs, t
def set_data(self, A, shape=None): """ Set the image array ACCEPTS: numeric/numarray/PIL Image A""" # check if data is PIL Image without importing Image if hasattr(A,'getpixel'): X = pil_to_array(A) else: X = asarray(A) # assume array if (X.typecode() != UInt8 or len(X.shape) != 3 or X.shape[2] > 4 or X.shape[2] < 3): cm.ScalarMappable.set_array(self, X) else: self._A = X self._imcache =None
def rank(x): """ Returns the rank of a matrix. The rank is understood here as the an estimation of the number of linearly independent rows or columns (depending on the size of the matrix). Note that numerix.mlab.rank() is not equivalent to Matlab's rank. This function is! """ x = asarray(x) u,s,v = numerix.mlab.svd(x) # maxabs = numerix.mlab.max(numerix.absolute(s)) is also possible. maxabs = norm(x) maxdim = numerix.mlab.max(numerix.shape(x)) tol = maxabs*maxdim*_eps_approx r = s>tol return asum(r)
def rank(x): """ Returns the rank of a matrix. The rank is understood here as the an estimation of the number of linearly independent rows or columns (depending on the size of the matrix). Note that MLab.rank() is not equivalent to Matlab's rank. This function is! """ x = numerix.asarray(x) u, s, v = MLab.svd(x) # maxabs = MLab.max(numerix.absolute(s)) is also possible. maxabs = norm(x) maxdim = MLab.max(numerix.shape(x)) tol = maxabs * maxdim * _eps_approx r = s > tol return MLab.sum(r)
def norm(x, y=2): """ Norm of a matrix or a vector according to Matlab. The description is taken from Matlab: For matrices... NORM(X) is the largest singular value of X, max(svd(X)). NORM(X,2) is the same as NORM(X). NORM(X,1) is the 1-norm of X, the largest column sum, = max(sum(abs((X)))). NORM(X,inf) is the infinity norm of X, the largest row sum, = max(sum(abs((X')))). NORM(X,'fro') is the Frobenius norm, sqrt(sum(diag(X'*X))). NORM(X,P) is available for matrix X only if P is 1, 2, inf or 'fro'. For vectors... NORM(V,P) = sum(abs(V).^P)^(1/P). NORM(V) = norm(V,2). NORM(V,inf) = max(abs(V)). NORM(V,-inf) = min(abs(V)). """ x = asarray(x) if numerix.mlab.rank(x) == 2: if y == 2: return numerix.mlab.max(numerix.mlab.svd(x)[1]) elif y == 1: return numerix.mlab.max(asum(absolute((x)))) elif y == 'inf': return numerix.mlab.max(asum(absolute((transpose(x))))) elif y == 'fro': return numerix.mlab.sqrt( asum(numerix.mlab.diag(matrixmultiply(transpose(x), x)))) else: verbose.report_error('Second argument not permitted for matrices') return None else: if y == 'inf': return numerix.mlab.max(absolute(x)) elif y == '-inf': return numerix.mlab.min(absolute(x)) else: return power(asum(power(absolute(x), y)), 1 / float(y))
def polyval(p, x): """ y = polyval(p,x) p is a vector of polynomial coeffients and y is the polynomial evaluated at x. Example code to remove a polynomial (quadratic) trend from y: p = polyfit(x, y, 2) trend = polyval(p, x) resid = y - trend See also polyfit """ x = asarray(x) + 0. p = reshape(p, (len(p), 1)) X = vander(x, len(p)) y = matrixmultiply(X, p) return reshape(y, x.shape)
def __init__(self, dpi, numsides, rotation=0, sizes=(1, ), **kwargs): """ Draw a regular polygon with numsides. sizes gives the area of the circle circumscribing the regular polygon and rotation is the rotation of the polygon in radians. offsets are a sequence of x,y tuples that give the centers of the polygon in data coordinates, and transOffset is the Transformation instance used to transform the centers onto the canvas. dpi is the figure dpi instance, and is required to do the area scaling. """ PatchCollection.__init__(self, **kwargs) self._sizes = asarray(sizes) self._dpi = dpi r = 1.0 / math.sqrt(math.pi) # unit area theta = (2 * math.pi / numsides) * arange(numsides) + rotation self._verts = zip(r * sin(theta), r * cos(theta))
def hist(y, bins=10, normed=0): """ Return the histogram of y with bins equally sized bins. If bins is an array, use the bins. Return value is (n,x) where n is the count for each bin in x If normed is False, return the counts in the first element of the return tuple. If normed is True, return the probability density n/(len(y)*dbin) If y has rank>1, it will be raveled Credits: the Numeric 22 documentation """ y = asarray(y) if len(y.shape)>1: y = ravel(y) if not iterable(bins): ymin, ymax = min(y), max(y) if ymin==ymax: ymin -= 0.5 ymax += 0.5 if bins==1: bins=ymax dy = (ymax-ymin)/bins bins = ymin + dy*arange(bins) n = searchsorted(sort(y), bins) n = diff(concatenate([n, [len(y)]])) if normed: db = bins[1]-bins[0] return 1/(len(y)*db)*n, bins else: return n, bins
def draw(self, renderer): if not self.get_visible(): return renderer.open_group('regpolycollection') self._transform.freeze() self._transOffset.freeze() self.update_scalarmappable() self._update_verts() scales = sqrt(asarray(self._sizes) * self._dpi.get() / 72.0) if is_string_like(self._edgecolors) and self._edgecolors[:2] == 'No': #self._edgecolors = self._facecolors self._linewidths = (0, ) # print 'in draw(), self._offsets = %s' % (`self._offsets`) renderer.draw_regpoly_collection(self.clipbox, self._offsets, self._transOffset, self._verts, scales, self._facecolors, self._edgecolors, self._linewidths, self._antialiaseds) self._transform.thaw() self._transOffset.thaw() renderer.close_group('regpolycollection')
def __init__( self, segments, # Can be None. linewidths=None, colors=None, antialiaseds=None, linestyle='solid', offsets=None, transOffset=None, #identity_transform(), norm=None, cmap=None, ): """ segments is a sequence of ( line0, line1, line2), where linen = (x0, y0), (x1, y1), ... (xm, ym), or the equivalent numerix array with two columns. Each line can be a different length. colors must be a tuple of RGBA tuples (eg arbitrary color strings, etc, not allowed). antialiaseds must be a sequence of ones or zeros linestyles is a string or dash tuple. Legal string values are solid|dashed|dashdot|dotted. The dash tuple is (offset, onoffseq) where onoffseq is an even length tuple of on and off ink in points. If linewidths, colors, or antialiaseds is None, they default to their rc params setting, in sequence form. If offsets and transOffset are not None, then offsets are transformed by transOffset and applied after the segments have been transformed to display coordinates. If offsets is not None but transOffset is None, then the offsets are added to the segments before any transformation. In this case, a single offset can be specified as offsets=(xo,yo), and this value will be added cumulatively to each successive segment, so as to produce a set of successively offset curves. norm = None, # optional for ScalarMappable cmap = None, # ditto The use of ScalarMappable is optional. If the ScalarMappable matrix _A is not None (ie a call to set_array has been made), at draw time a call to scalar mappable will be made to set the colors. """ Collection.__init__(self) ScalarMappable.__init__(self, norm, cmap) if linewidths is None: linewidths = (rcParams['lines.linewidth'], ) if colors is None: colors = (rcParams['lines.color'], ) if antialiaseds is None: antialiaseds = (rcParams['lines.antialiased'], ) self._colors = colorConverter.to_rgba_list(colors) self._aa = antialiaseds self._lw = linewidths self.set_linestyle(linestyle) self._uniform_offsets = None if offsets is not None: offsets = asarray(offsets) if len(offsets.shape) == 1: offsets = offsets[newaxis, :] # Make it Nx2. if transOffset is None: if offsets is not None: self._uniform_offsets = offsets offsets = None transOffset = identity_transform() self._offsets = offsets self._transOffset = transOffset self.set_segments(segments)
def julian2num(j): 'convert a Julian date (or sequence) to a matplotlib date (or sequence)' if iterable(j): j = asarray(j) return j + 1721425.5
def num2epoch(d): """ convert days since 0001 to epoch. d can be a number or sequence """ spd = 24.*3600. return (asarray(d)-719163)*spd
def num2julian(n): 'convert a matplotlib date (or seguence) to a Julian date (or sequence)' if iterable(n): n = asarray(n) return n - 1721425.5
def break_linecontour(self, linecontour, rot, labelwidth, ind): "break a contour in two contours at the location of the label" lcsize = len(linecontour) hlw = int(labelwidth / 2) #length of label in screen coords ylabel = abs(hlw * sin(rot * pi / 180)) xlabel = abs(hlw * cos(rot * pi / 180)) trans = self.ax.transData slc = trans.seq_xy_tups(linecontour) x, y = slc[ind] xx = asarray(slc)[:, 0].copy() yy = asarray(slc)[:, 1].copy() #indices which are under the label inds = nonzero(((xx < x + xlabel) & (xx > x - xlabel)) & ((yy < y + ylabel) & (yy > y - ylabel))) if len(inds) > 0: #if the label happens to be over the beginning of the #contour, the entire contour is removed, i.e. #indices to be removed are #inds= [0,1,2,3,305,306,307] #should rewrite this in a better way linds = nonzero(inds[1:] - inds[:-1] != 1) if inds[0] == 0 and len(linds) != 0: ii = inds[linds[0]] lc1 = linecontour[ii + 1:inds[ii + 1]] lc2 = [] else: lc1 = linecontour[:inds[0]] lc2 = linecontour[inds[-1] + 1:] else: lc1 = linecontour[:ind] lc2 = linecontour[ind + 1:] if rot < 0: new_x1, new_y1 = x - xlabel, y + ylabel new_x2, new_y2 = x + xlabel, y - ylabel else: new_x1, new_y1 = x - xlabel, y - ylabel new_x2, new_y2 = x + xlabel, y + ylabel new_x1d, new_y1d = trans.inverse_xy_tup((new_x1, new_y1)) new_x2d, new_y2d = trans.inverse_xy_tup((new_x2, new_y2)) new_xy1 = array(((new_x1d, new_y1d), )) new_xy2 = array(((new_x2d, new_y2d), )) if rot > 0: if (len(lc1) > 0 and (lc1[-1][0] <= new_x1d) and (lc1[-1][1] <= new_y1d)): lc1 = concatenate((lc1, new_xy1)) #lc1.append((new_x1d, new_y1d)) if (len(lc2) > 0 and (lc2[0][0] >= new_x2d) and (lc2[0][1] >= new_y2d)): lc2 = concatenate((new_xy2, lc2)) #lc2.insert(0, (new_x2d, new_y2d)) else: if (len(lc1) > 0 and ((lc1[-1][0] <= new_x1d) and (lc1[-1][1] >= new_y1d))): lc1 = concatenate((lc1, new_xy1)) #lc1.append((new_x1d, new_y1d)) if (len(lc2) > 0 and ((lc2[0][0] >= new_x2d) and (lc2[0][1] <= new_y2d))): lc2 = concatenate((new_xy2, lc2)) #lc2.insert(0, (new_x2d, new_y2d)) return [lc1, lc2]
def _contour_args(self, *args): if self.filled: fn = 'contourf' else: fn = 'contour' Nargs = len(args) if Nargs <= 2: z = args[0] x, y = self._initialize_x_y(z) elif Nargs <= 4: x, y, z = self._check_xyz(args[:3]) else: raise TypeError("Too many arguments to %s; see help(%s)" % (fn, fn)) z = ma.asarray( z) # Convert to native masked array format if necessary. self.zmax = ma.maximum(z) self.zmin = ma.minimum(z) self._auto = False if self.levels is None: if Nargs == 1 or Nargs == 3: lev = self._autolev(z, 7) else: # 2 or 4 args level_arg = args[-1] if type(level_arg) == int: lev = self._autolev(z, level_arg) elif iterable(level_arg) and len(shape(level_arg)) == 1: lev = array([float(fl) for fl in level_arg]) else: raise TypeError( "Last %s arg must give levels; see help(%s)" % (fn, fn)) if self.filled and len(lev) < 2: raise ValueError("Filled contours require at least 2 levels.") # Workaround for cntr.c bug wrt masked interior regions: #if filled: # z = ma.masked_array(z.filled(-1e38)) # It's not clear this is any better than the original bug. self.levels = lev #if self._auto and self.extend in ('both', 'min', 'max'): # raise TypeError("Auto level selection is inconsistent " # + "with use of 'extend' kwarg") self._levels = list(self.levels) if self.extend in ('both', 'min'): self._levels.insert(0, self.zmin - 1) if self.extend in ('both', 'max'): self._levels.append(self.zmax + 1) self._levels = asarray(self._levels) self.vmin = amin(self.levels) # alternative would be self.layers self.vmax = amax(self.levels) if self.extend in ('both', 'min') or self.clip_ends: self.vmin = 2 * self.levels[0] - self.levels[1] if self.extend in ('both', 'max') or self.clip_ends: self.vmax = 2 * self.levels[-1] - self.levels[-2] self.layers = self._levels # contour: a line is a thin layer if self.filled: self.layers = 0.5 * (self._levels[:-1] + self._levels[1:]) if self.extend in ('both', 'min') or self.clip_ends: self.layers[0] = 0.5 * (self.vmin + self._levels[1]) if self.extend in ('both', 'max') or self.clip_ends: self.layers[-1] = 0.5 * (self.vmax + self._levels[-2]) return (x, y, z)
def set_segments(self, segments): if segments is None: return self._segments = [asarray(seg) for seg in segments] if self._uniform_offsets is not None: self._add_offsets()