def __call__(self): 'Return the locations of the ticks' self.verify_intervals() b=self._base vmin, vmax = self.viewInterval.get_bounds() vmin = math.log(vmin)/math.log(b) vmax = math.log(vmax)/math.log(b) if vmax<vmin: vmin, vmax = vmax, vmin ticklocs = [] numdec = math.floor(vmax)-math.ceil(vmin) if self._subs is None: # autosub if numdec>10: subs = array([1.0]) elif numdec>6: subs = arange(2.0, b, 2.0) else: subs = arange(2.0, b) else: subs = self._subs stride = 1 while numdec/stride+1 > self.numticks: stride += 1 for decadeStart in b**arange(math.floor(vmin),math.ceil(vmax)+stride, stride): ticklocs.extend( subs*decadeStart ) return array(ticklocs)
def __call__(self): 'Return the locations of the ticks' self.verify_intervals() b=self._base vmin, vmax = self.viewInterval.get_bounds() vmin = math.log(vmin)/math.log(b) vmax = math.log(vmax)/math.log(b) if vmax<vmin: vmin, vmax = vmax, vmin ticklocs = [] numdec = math.floor(vmax)-math.ceil(vmin) if self._subs is None: # autosub if numdec>10: subs = array([1.0]) elif numdec>6: subs = arange(2.0, b, 2.0) else: subs = arange(2.0, b) else: subs = self._subs for decadeStart in b**arange(math.floor(vmin),math.ceil(vmax)): ticklocs.extend( subs*decadeStart ) if(len(subs) and subs[0]==1.0): ticklocs.append(b**math.ceil(vmax)) ticklocs = array(ticklocs) ind = nonzero(logical_and(ticklocs>=b**vmin , ticklocs<=b**vmax)) ticklocs = take(ticklocs,ind) return ticklocs
def meshgrid(x,y): """ For vectors x, y with lengths Nx=len(x) and Ny=len(y), return X, Y where X and Y are (Ny, Nx) shaped arrays with the elements of x and y repeated to fill the matrix EG, [X, Y] = meshgrid([1,2,3], [4,5,6,7]) X = 1 2 3 1 2 3 1 2 3 1 2 3 Y = 4 4 4 5 5 5 6 6 6 7 7 7 """ x = array(x) y = array(y) numRows, numCols = len(y), len(x) # yes, reversed x.shape = 1, numCols X = repeat(x, numRows) y.shape = numRows,1 Y = repeat(y, numCols, 1) return X, Y
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 """ 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 = array(X) 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 __call__(self, value): vmin = self.vmin vmax = self.vmax if type(value) in [IntType, FloatType]: vtype = 'scalar' val = array([value]) else: vtype = 'array' val = array(value) if vmin is None or vmax is None: rval = ravel(val) if vmin is None: vmin = min(rval) if vmax is None: vmax = max(rval) if vmin > vmax: raise ValueError("minvalue must be less than or equal to maxvalue") elif vmin==vmax: return 0.*value else: val = where(val<vmin, vmin, val) val = where(val>vmax, vmax, val) result = divide(val-vmin, vmax-vmin) if vtype == 'scalar': result = result[0] return result
def figaspect(arg): """ Create a figure with specified aspect ratio. If arg is a number, use that aspect ratio. If arg is an array, figaspect will determine the width and height for a figure that would fit array preserving aspcect ratio. The figure width, height in inches are returned. Be sure to create an axes with equal with and height, eg Example usage: # make a figure twice as tall as it is wide w, h = figaspect(2.) fig = Figure(figsize=(w,h)) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8]) ax.imshow(A, **kwargs) # make a figure with the proper aspect for an array A = rand(5,3) w, h = figaspect(A) fig = Figure(figsize=(w,h)) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8]) ax.imshow(A, **kwargs) Thanks to Fernando Perez for this function """ isarray = hasattr(arg, "shape") # min/max sizes to respect when autoscaling. If John likes the idea, they # could become rc parameters, for now they're hardwired. figsize_min = array((4.0, 2.0)) # min length for width/height figsize_max = array((16.0, 16.0)) # max length for width/height # figsize_min = rcParams['figure.figsize_min'] # figsize_max = rcParams['figure.figsize_max'] # Extract the aspect ratio of the array if isarray: nr, nc = arg.shape[:2] arr_ratio = float(nr) / nc else: arr_ratio = float(arg) # Height of user figure defaults fig_height = rcParams["figure.figsize"][1] # New size for the figure, keeping the aspect ratio of the caller newsize = array((fig_height / arr_ratio, fig_height)) # Sanity checks, don't drop either dimension below figsize_min newsize /= min(1.0, *(newsize / figsize_min)) # Avoid humongous windows as well newsize /= max(1.0, *(newsize / figsize_max)) # Finally, if we have a really funky aspect ratio, break it but respect # the min/max dimensions (we don't want figures 10 feet tall!) newsize = clip(newsize, figsize_min, figsize_max) return newsize
def meshgrid(x, y): """ For vectors x, y with lengths Nx=len(x) and Ny=len(y), return X, Y where X and Y are (Ny, Nx) shaped arrays with the elements of x and y repeated to fill the matrix EG, [X, Y] = meshgrid([1,2,3], [4,5,6,7]) X = 1 2 3 1 2 3 1 2 3 1 2 3 Y = 4 4 4 5 5 5 6 6 6 7 7 7 """ x = array(x) y = array(y) numRows, numCols = len(y), len(x) # yes, reversed x.shape = 1, numCols X = repeat(x, numRows) y.shape = numRows, 1 Y = repeat(y, numCols, 1) return X, Y
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 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 __call__(self): 'Return the locations of the ticks' self.verify_intervals() b = self._base vmin, vmax = self.viewInterval.get_bounds() vmin = math.log(vmin) / math.log(b) vmax = math.log(vmax) / math.log(b) if vmax < vmin: vmin, vmax = vmax, vmin ticklocs = [] numdec = math.floor(vmax) - math.ceil(vmin) if self._subs is None: # autosub if numdec > 10: subs = array([1.0]) elif numdec > 6: subs = arange(2.0, b, 2.0) else: subs = arange(2.0, b) else: subs = self._subs stride = 1 while numdec / stride + 1 > self.numticks: stride += 1 for decadeStart in b**arange(math.floor(vmin), math.ceil(vmax) + stride, stride): ticklocs.extend(subs * decadeStart) return array(ticklocs)
def figaspect(arg): """ Create a figure with specified aspect ratio. If arg is a number, use that aspect ratio. If arg is an array, figaspect will determine the width and height for a figure that would fit array preserving aspect ratio. The figure width, height in inches are returned. Be sure to create an axes with equal with and height, eg Example usage: # make a figure twice as tall as it is wide w, h = figaspect(2.) fig = Figure(figsize=(w,h)) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8]) ax.imshow(A, **kwargs) # make a figure with the proper aspect for an array A = rand(5,3) w, h = figaspect(A) fig = Figure(figsize=(w,h)) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8]) ax.imshow(A, **kwargs) Thanks to Fernando Perez for this function """ isarray = hasattr(arg, 'shape') # min/max sizes to respect when autoscaling. If John likes the idea, they # could become rc parameters, for now they're hardwired. figsize_min = array((4.0, 2.0)) # min length for width/height figsize_max = array((16.0, 16.0)) # max length for width/height #figsize_min = rcParams['figure.figsize_min'] #figsize_max = rcParams['figure.figsize_max'] # Extract the aspect ratio of the array if isarray: nr, nc = arg.shape[:2] arr_ratio = float(nr) / nc else: arr_ratio = float(arg) # Height of user figure defaults fig_height = rcParams['figure.figsize'][1] # New size for the figure, keeping the aspect ratio of the caller newsize = array((fig_height / arr_ratio, fig_height)) # Sanity checks, don't drop either dimension below figsize_min newsize /= min(1.0, *(newsize / figsize_min)) # Avoid humongous windows as well newsize /= max(1.0, *(newsize / figsize_max)) # Finally, if we have a really funky aspect ratio, break it but respect # the min/max dimensions (we don't want figures 10 feet tall!) newsize = clip(newsize, figsize_min, figsize_max) return newsize
def vec_pad_ones(xs, ys, zs): try: try: vec = nx.array([xs, ys, zs, nx.ones(xs.shape)]) except (AttributeError, TypeError): vec = nx.array([xs, ys, zs, nx.ones((len(xs)))]) except TypeError: vec = nx.array([xs, ys, zs, 1]) return vec
def test_proj_make_M(E=None): # eye point E = E or nx.array([1, -1, 2]) * 1000 #E = nx.array([20,10,20]) R = nx.array([1, 1, 1]) * 100 V = nx.array([0, 0, 1]) viewM = view_transformation(E, R, V) perspM = persp_transformation(100, -100) M = nx.matrixmultiply(perspM, viewM) return M
def __init__(self, x, y, dx, dy, width=1.0, **kwargs): """Draws an arrow, starting at (x,y), direction and length given by (dx,dy) the width of the arrow is scaled by width """ arrow = array([[0.0, 0.1], [0.0, -0.1], [0.8, -0.1], [0.8, -0.3], [1.0, 0.0], [0.8, 0.3], [0.8, 0.1]]) L = sqrt(dx ** 2 + dy ** 2) or 1 # account for div by zero arrow[:, 0] *= L arrow[:, 1] *= width cx = float(dx) / L sx = float(dy) / L M = array([[cx, sx], [-sx, cx]]) verts = matrixmultiply(arrow, M) + [x, y] Polygon.__init__(self, [tuple(t) for t in verts], **kwargs)
def get_rotation_matrix(self, x0, y0): theta = pi / 180.0 * self.get_rotation() # translate x0,y0 to origin Torigin = array([[1, 0, -x0], [0, 1, -y0], [0, 0, 1]]) # rotate by theta R = array([[cos(theta), -sin(theta), 0], [sin(theta), cos(theta), 0], [0, 0, 1]]) # translate origin back to x0,y0 Tback = array([[1, 0, x0], [0, 1, y0], [0, 0, 1]]) return dot(dot(Tback, R), Torigin)
def __init__(self, x, y, dx, dy, width=1.0, **kwargs): """Draws an arrow, starting at (x,y), direction and length given by (dx,dy) the width of the arrow is scaled by width """ arrow = array([[0.0, 0.1], [0.0, -0.1], [0.8, -0.1], [0.8, -0.3], [1.0, 0.0], [0.8, 0.3], [0.8, 0.1]]) L = sqrt(dx**2 + dy**2) or 1 # account for div by zero arrow[:, 0] *= L arrow[:, 1] *= width cx = float(dx) / L sx = float(dy) / L M = array([[cx, sx], [-sx, cx]]) verts = matrixmultiply(arrow, M) + [x, y] Polygon.__init__(self, [tuple(t) for t in verts], **kwargs)
def _contour_args(self, filled, 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 = ma.asarray(z) # Convert to native masked array format if necessary. if Nargs == 1 or Nargs == 3: lev = self._autolev(z, 7, filled) else: # 2 or 4 args level_arg = args[-1] if type(level_arg) == int: lev = self._autolev(z, level_arg, filled) 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 filled and len(lev) < 2: raise ValueError("Filled contours require at least 2 levels.") self.ax.set_xlim((ma.minimum(x), ma.maximum(x))) self.ax.set_ylim((ma.minimum(y), ma.maximum(y))) # 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. return (x, y, z, lev)
def _set_format(self): # set the format string to format all the ticklabels locs = (array(self.locs)-self.offset) / 10**self.orderOfMagnitude+1e-15 sigfigs = [len(str('%1.3f'% loc).split('.')[1].rstrip('0')) \ for loc in locs] sigfigs.sort() self.format = '%1.' + str(sigfigs[-1]) + 'f'
def _convert_xy(self): x, y = (self._xy[0], self._xy[1]) if self.is_unitsmgr_set(): mgr = self.get_unitsmgr() x, y = mgr._convert_units((x, self._xunits), (y, self._yunits)) return array((x, y), Float)
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 center_matrix(M, dim=0): """ Return the matrix M with each row having zero mean and unit std if dim=1, center columns rather than rows """ # todo: implement this w/o loop. Allow optional arg to specify # dimension to remove the mean from if dim == 1: M = transpose(M) M = array(M, Float) if len(M.shape) == 1 or M.shape[0] == 1 or M.shape[1] == 1: M = M - mean(M) sigma = std(M) if sigma > 0: M = divide(M, sigma) if dim == 1: M = transpose(M) return M for i in range(M.shape[0]): M[i] -= mean(M[i]) sigma = std(M[i]) if sigma > 0: M[i] = divide(M[i], sigma) if dim == 1: M = transpose(M) return M
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 __call__(self): 'Return the locations of the ticks' self.verify_intervals() b=self.base subs=self.subs vmin, vmax = self.viewInterval.get_bounds() vmin = math.log(vmin)/math.log(b) vmax = math.log(vmax)/math.log(b) if vmax<vmin: vmin, vmax = vmax, vmin ticklocs = [] for decadeStart in b**arange(math.floor(vmin),math.ceil(vmax)): ticklocs.extend( subs*decadeStart ) if(len(subs) and subs[0]==1.0): ticklocs.append(b**math.ceil(vmax)) ticklocs = array(ticklocs) ind = nonzero(logical_and(ticklocs>=b**vmin , ticklocs<=b**vmax)) ticklocs = take(ticklocs,ind) return ticklocs
def _clicked(self, event): if event.button != 1: return if event.inaxes != self.ax: return xy = self.ax.transAxes.inverse_xy_tup((event.x, event.y)) pclicked = array([xy[0], xy[1]]) def inside(p): pcirc = array([p.center[0], p.center[1]]) return dist(pclicked, pcirc) < p.radius for p, t in zip(self.circles, self.labels): if t.get_window_extent().contains(event.x, event.y) or inside(p): inp = p thist = t break else: return for p in self.circles: if p == inp: color = self.activecolor else: color = self.ax.get_axis_bgcolor() p.set_facecolor(color) if self.drawon: self.ax.figure.canvas.draw() if not self.eventson: return for cid, func in self.observers.items(): func(thist.get_text())
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 zalpha(colors, zs): """Modify the alphas of the color list according to depth""" colors = get_colors(colors, len(zs)) norm = normalize(min(zs), max(zs)) sats = nx.array([1 - norm(z) * 0.7 for z in zs]) colors = [(c[0], c[1], c[2], c[3] * s) for c, s in zip(colors, sats)] return colors
def line2d_seg_dist(p0, p1, p): """distance(s) from line defined by p0 - p1 to point(s) p p[0] = x(s) p[1] = y(s) intersection point p = p0 + u*(p1-p0) and intersection point lies within segement if u is between 0 and 1 """ p, p0, p1 = map(nx.asarray, (p[:2], p0[:2], p1[:2])) x, y = p x0, y0 = p0 x1, y1 = p1 # u = ((x - x0) * (x1 - x0) + (y - y0) * (y1 - y0)) / (dist2d(p0, p1) * dist2d(p0, p1)) # def dist(p, p0, p1, u): if u > 0 and u < 1: pi = p0 + u * (p1 - p0) return dist2d(p, pi) else: return nx.minimum(dist2d(p, p0), dist2d(p, p1)) if not iterable(u): return dist(p, p0, p1, u) else: # for each point calculate dist pt = nx.transpose(p) return nx.array([dist(pe, p0, p1, ue) for pe, ue in zip(pt, u)])
def _init(self): rgb = array([colorConverter.to_rgb(c) for c in self.colors], typecode=Float) self._lut = zeros((self.N + 3, 4), Float) self._lut[:-3, :-1] = rgb self._isinit = True self._set_extremes()
def _convert_xy(self): x, y = (self._xy[0], self._xy[1]) if (self.is_unitsmgr_set()): mgr = self.get_unitsmgr() x, y = mgr._convert_units((x, self._xunits), (y, self._yunits)) return array((x, y), Float)
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 orth(A): """ Orthogonalization procedure by Matlab. The description is taken from its help: Q = ORTH(A) is an orthonormal basis for the range of A. That is, Q'*Q = I, the columns of Q span the same space as the columns of A, and the number of columns of Q is the rank of A. """ A = array(A) U,S,V = numerix.mlab.svd(A) m,n = numerix.shape(A) if m > 1: s = S elif m == 1: s = S[0] else: s = 0 tol = numerix.mlab.max((m,n)) * numerix.mlab.max(s) * _eps_approx r = asum(s > tol) Q = take(U,range(r),1) return Q
def zalpha(colors, zs): """Modify the alphas of the color list according to depth""" colors = get_colors(colors,len(zs)) norm = normalize(min(zs),max(zs)) sats = nx.array([1-norm(z)*0.7 for z in zs]) colors = [(c[0],c[1],c[2],c[3]*s) for c,s in zip(colors,sats)] return colors
def _clicked(self, event): if event.button !=1 : return if event.inaxes != self.ax: return xy = self.ax.transAxes.inverse_xy_tup((event.x, event.y)) pclicked = array([xy[0], xy[1]]) def inside(p): pcirc = array([p.center[0], p.center[1]]) return dist(pclicked, pcirc) < p.radius for p,t in zip(self.circles, self.labels): if t.get_window_extent().contains(event.x, event.y) or inside(p): inp = p thist = t break else: return for p in self.circles: if p==inp: color = self.activecolor else: color = self.ax.get_axis_bgcolor() p.set_facecolor(color) if self.drawon: self.ax.figure.canvas.draw() if not self.eventson: return for cid, func in self.observers.items(): func(thist.get_text())
def orth(A): """ Orthogonalization procedure by Matlab. The description is taken from its help: Q = ORTH(A) is an orthonormal basis for the range of A. That is, Q'*Q = I, the columns of Q span the same space as the columns of A, and the number of columns of Q is the rank of A. """ A = numerix.array(A) U,S,V = MLab.svd(A) m,n = numerix.shape(A) if m > 1: s = S elif m == 1: s = S[0] else: s = 0 tol = MLab.max((m,n)) * MLab.max(s) * _eps_approx r = MLab.sum(s > tol) Q = numerix.take(U,range(r),1) return Q
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. 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 self.layers = self.levels # contour: a line is a thin layer if self.filled: self.layers = 0.5 * (self.levels[:-1] + self.levels[1:]) return (x, y, z)
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 print_label(self, linecontour, labelwidth): "if contours are too short, don't plot a label" lcsize = len(linecontour) if lcsize > 10 * labelwidth: return 1 xmax = amax(array(linecontour)[:, 0]) xmin = amin(array(linecontour)[:, 0]) ymax = amax(array(linecontour)[:, 1]) ymin = amin(array(linecontour)[:, 1]) lw = labelwidth if (xmax - xmin) > 1.2 * lw or (ymax - ymin) > 1.2 * lw: return 1 else: return 0
def print_label(self, linecontour,labelwidth): "if contours are too short, don't plot a label" lcsize = len(linecontour) if lcsize > 10 * labelwidth: return 1 xmax = amax(array(linecontour)[:,0]) xmin = amin(array(linecontour)[:,0]) ymax = amax(array(linecontour)[:,1]) ymin = amin(array(linecontour)[:,1]) lw = labelwidth if (xmax - xmin) > 1.2* lw or (ymax - ymin) > 1.2 * lw: return 1 else: return 0
def center_matrix(M, dim=0): """ Return the matrix M with each row having zero mean and unit std if dim=1, center columns rather than rows """ # todo: implement this w/o loop. Allow optional arg to specify # dimension to remove the mean from if dim==1: M = transpose(M) M = array(M, Float) if len(M.shape)==1 or M.shape[0]==1 or M.shape[1]==1: M = M-mean(M) sigma = std(M) if sigma>0: M = divide(M, sigma) if dim==1: M=transpose(M) return M for i in range(M.shape[0]): M[i] -= mean(M[i]) sigma = std(M[i]) if sigma>0: M[i] = divide(M[i], sigma) if dim==1: M=transpose(M) return M
def get_proj(self): """Create the projection matrix from the current viewing position. elev stores the elevation angle in the z plane azim stores the azimuth angle in the x,y plane dist is the distance of the eye viewing point from the object point. """ relev,razim = nx.pi * self.elev/180, nx.pi * self.azim/180 xmin,xmax = self.get_w_xlim() ymin,ymax = self.get_w_ylim() zmin,zmax = self.get_w_zlim() # transform to uniform world coordinates 0-1.0,0-1.0,0-1.0 worldM = proj3d.world_transformation(xmin,xmax, ymin,ymax, zmin,zmax) # look into the middle of the new coordinates R = nx.array([0.5,0.5,0.5]) # xp = R[0] + nx.cos(razim)*nx.cos(relev)*self.dist yp = R[1] + nx.sin(razim)*nx.cos(relev)*self.dist zp = R[2] + nx.sin(relev)*self.dist E = nx.array((xp, yp, zp)) # self.eye = E self.vvec = R - E self.vvec = self.vvec / proj3d.mod(self.vvec) if abs(relev) > nx.pi/2: # upside down V = nx.array((0,0,-1)) else: V = nx.array((0,0,1)) zfront,zback = -self.dist,self.dist viewM = proj3d.view_transformation(E,R,V) perspM = proj3d.persp_transformation(zfront,zback) M0 = nx.matrixmultiply(viewM,worldM) M = nx.matrixmultiply(perspM,M0) return M
def subs(self,subs): """ set the minor ticks the log scaling every base**i*subs[j] """ if subs is None: self._subs = None # autosub else: self._subs = array(subs)+0.0
def idwt2(coeffs, wavelet, mode='sym'): """ 2D Inverse Discrete Wavelet Transform. Reconstruct data from coefficients arrays. coeffs - four 2D coefficients arrays arranged as follows: (approximation, (horizontal details, vertical details, diagonal details) ) wavelet - wavelet to use (Wavelet object or name string) mode - signal extension mode, see MODES """ if len(coeffs) != 2 or len(coeffs[1]) != 3: raise ValueError("Invalid coeffs param") # L -low-pass data, H - high-pass data LL, (LH, HL, HH) = coeffs (LL, LH, HL, HH) = (transpose(LL), transpose(LH), transpose(HL), transpose(HH)) for arr in (LL, LH, HL, HH): if len(arr.shape) != 2: raise TypeError("All input coefficients arrays must be 2D") del arr if not isinstance(wavelet, Wavelet): wavelet = Wavelet(wavelet) mode = MODES.from_object(mode) # idwt columns L = [] append_L = L.append for rowL, rowH in izip(LL, LH): append_L(idwt(rowL, rowH, wavelet, mode, 1)) del LL, LH H = [] append_H = H.append for rowL, rowH in izip(HL, HH): append_H(idwt(rowL, rowH, wavelet, mode, 1)) del HL, HH L = transpose(L) H = transpose(H) # idwt rows data = [] append_data = data.append for rowL, rowH in izip(L, H): append_data(idwt(rowL, rowH, wavelet, mode, 1)) return array(data, default_dtype)
def _get_verts(self): x, y = self.center l, r = x - width / 2.0, x + width / 2.0 b, t = y - height / 2.0, y + height / 2.0 if self.is_unitsmgr_set(): mgr = self.get_unitsmgr() x, l, r = mgr._convert_units((x, self._xunits), (l, self._xunits), (r, self._xunits)) y, b, t = mgr._convert_units((y, self._yunits), (b, self._yunits), (t, self._yunits)) return array(((x, y), (l, y), (x, t), (r, y), (x, b)), Float)
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 _hide_cross(a, b): """ Cross product of two vectors A x B = <Ay*Bz - Az*By, Az*Bx - Ax*Bz, Ax*By - Ay*Bx> a x b = [a2b3 - a3b2, a3b1 - a1b3, a1b2 - a2b1] """ return nx.array([ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ])
def _set_clip(self): if not self._useDataClipping: return #self._logcache = None try: self._xmin, self._xmax except AttributeError: indx = arange(len(self._x)) else: if not hasattr(self, '_xsorted'): self._xsorted = self._is_sorted(self._x) if len(self._x) == 1: indx = [0] elif self._xsorted: # for really long signals, if we know they are sorted # on x we can save a lot of time using search sorted # since the alternative approach requires 3 O(len(x) ) ops indMin, indMax = searchsorted(self._x, array([self._xmin, self._xmax])) indMin = max(0, indMin - 1) indMax = min(indMax + 1, len(self._x)) skip = 0 if self._lod: # if level of detail is on, decimate the data # based on pixel width raise NotImplementedError('LOD deprecated') l, b, w, h = self.get_window_extent().get_bounds() skip = int((indMax - indMin) / w) if skip > 0: indx = arange(indMin, indMax, skip) else: indx = arange(indMin, indMax) else: indx = nonzero( logical_and(self._x >= self._xmin, self._x <= self._xmax)) self._xc = take(self._x, indx) self._yc = take(self._y, indx) # y data clipping for connected lines can introduce horizontal # line artifacts near the clip region. If you really need y # clipping for efficiency, consider using plot(y,x) instead. if (self._yc.shape == self._xc.shape and self._linestyle is None): try: self._ymin, self._ymax except AttributeError: indy = arange(len(self._yc)) else: indy = nonzero( logical_and(self._yc >= self._ymin, self._yc <= self._ymax)) else: indy = arange(len(self._yc)) self._xc = take(self._xc, indy) self._yc = take(self._yc, indy)
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(array(linecontour)[:, 0], (xsize, ysize)) YY = resize(array(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) angle = arctan2(ylast - yfirst, xlast - xfirst) rotation = angle[ind] * 180 / pi if rotation > 90: rotation = rotation - 180 if rotation < -90: rotation = 180 + rotation dind = list(linecontour).index((x, y)) return x, y, rotation, dind
def _set_clip(self): if not self._useDataClipping: return # self._logcache = None try: self._xmin, self._xmax except AttributeError: indx = arange(len(self._x)) else: if not hasattr(self, "_xsorted"): self._xsorted = self._is_sorted(self._x) if len(self._x) == 1: indx = [0] elif self._xsorted: # for really long signals, if we know they are sorted # on x we can save a lot of time using search sorted # since the alternative approach requires 3 O(len(x) ) ops indMin, indMax = searchsorted(self._x, array([self._xmin, self._xmax])) indMin = max(0, indMin - 1) indMax = min(indMax + 1, len(self._x)) skip = 0 if self._lod: # if level of detail is on, decimate the data # based on pixel width raise NotImplementedError("LOD deprecated") l, b, w, h = self.get_window_extent().get_bounds() skip = int((indMax - indMin) / w) if skip > 0: indx = arange(indMin, indMax, skip) else: indx = arange(indMin, indMax) else: indx = nonzero(logical_and(self._x >= self._xmin, self._x <= self._xmax)) self._xc = take(self._x, indx) self._yc = take(self._y, indx) # y data clipping for connected lines can introduce horizontal # line artifacts near the clip region. If you really need y # clipping for efficiency, consider using plot(y,x) instead. if self._yc.shape == self._xc.shape and self._linestyle is None: try: self._ymin, self._ymax except AttributeError: indy = arange(len(self._yc)) else: indy = nonzero(logical_and(self._yc >= self._ymin, self._yc <= self._ymax)) else: indy = arange(len(self._yc)) self._xc = take(self._xc, indy) self._yc = take(self._yc, indy)
def longest_contiguous_ones(x): """ return the indicies of the longest stretch of contiguous ones in x, assuming x is a vector of zeros and ones. """ if len(x)==0: return array([]) ind = find(x==0) if len(ind)==0: return arange(len(x)) if len(ind)==len(x): return array([]) y = zeros( (len(x)+2,), x.typecode()) y[1:-1] = x dif = diff(y) up = find(dif == 1); dn = find(dif == -1); ind = find( dn-up == max(dn - up)) ind = arange(take(up, ind), take(dn, ind)) return ind
def get_rotation_matrix(self, x0, y0): theta = pi/180.0*self.get_rotation() # translate x0,y0 to origin Torigin = array([ [1, 0, -x0], [0, 1, -y0], [0, 0, 1 ]]) # rotate by theta R = array([ [cos(theta), -sin(theta), 0], [sin(theta), cos(theta), 0], [0, 0, 1]]) # translate origin back to x0,y0 Tback = array([ [1, 0, x0], [0, 1, y0], [0, 0, 1 ]]) return dot(dot(Tback,R), Torigin)
def longest_contiguous_ones(x): """ return the indicies of the longest stretch of contiguous ones in x, assuming x is a vector of zeros and ones. """ if len(x) == 0: return array([]) ind = find(x == 0) if len(ind) == 0: return arange(len(x)) if len(ind) == len(x): return array([]) y = zeros((len(x) + 2, ), typecode(x)) y[1:-1] = x dif = diff(y) up = find(dif == 1) dn = find(dif == -1) ind = find(dn - up == max(dn - up)) ind = arange(take(up, ind), take(dn, ind)) return ind
def detrend_linear(x): "Return x minus best fit line; 'linear' detrending " # I'm going to regress x on xx=range(len(x)) and return x - # (b*xx+a). Now that I have polyfit working, I could convert the # code here, but if it ain't broke, don't fix it! xx = arange(float(len(x))) X = transpose(array([xx]+[x])) C = cov(X) b = C[0,1]/C[0,0] a = mean(x) - b*mean(xx) return x-(b*xx+a)
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(array(linecontour)[:,0],(xsize, ysize)) YY = resize(array(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) angle = arctan2(ylast - yfirst, xlast - xfirst) rotation = angle[ind]*180/pi if rotation > 90: rotation = rotation -180 if rotation < -90: rotation = 180 + rotation dind = list(linecontour).index((x,y)) return x,y, rotation, dind