def fit(self, x, y): t0 = time.time() assert set(y.flatten()) == set( [0, 1]), "y data (target data) needs to have only 0s and 1s" # determine the clusters self.clus = sk.cluster.MiniBatchKMeans(n_clusters=self.n_clusters) self.clus.fit(x) # determine the nearest neighbor for each data point nns = sk.neighbors.NearestNeighbors(n_neighbors=self.n_neighbors) nns.fit(x) neighbor_dist, neighbor_idx = nns.kneighbors( self.clus.cluster_centers_, n_neighbors=self.n_neighbors) # compute the cluster means self.cluster_x = self.clus.cluster_centers_ self.cluster_y = array( map(lambda i: nanmean(y[neighbor_idx[i, :]]), xrange(shape(self.cluster_x)[0]))) # make the interpolator if self.interpolator == 'linear': self.iterpol = interpolate.LinearNDInterpolator(self.cluster_x, self.cluster_y, fill_value=nan) else: self.iterpol = interpolate.CloughTocher2DInterpolator( self.cluster_x, self.cluster_y, fill_value=nan) self.nnb_iterpol = interpolate.NearestNDInterpolator( self.cluster_x, self.cluster_y) print "fit elapsed time: %.02f minutes" % ((time.time() - t0) / 60.)
def initInterpolation(self, nsamples=1): self.interpolators = [] self.nsamples = nsamples for i in range(nsamples): temp = zip(*self.gridpoints( sample=(nsamples != 1), flag='x', extendToBorder=True)) self.interpolators.append( interpolate.CloughTocher2DInterpolator(list(temp[0]), temp[1], fill_value=0.)) # polynomial interpolation nneighbor = 2 for k in self.data: kk = np.asarray(k) kmin = np.maximum(kk - np.full(self.dim, nneighbor, dtype=int), np.zeros(self.dim)).astype(int) kmax = np.minimum(kk + np.full(self.dim, nneighbor, dtype=int), self.nbin - 1).astype(int) degree = kmax - kmin self.deg[k] = degree xx = self.x(k) dat = [ np.append( self.x(x + kmin), self.data[tuple(x + kmin)].gety(sample=(nsamples != 1))) for x in np.ndindex(*(degree + 1)) ] x, y, z = np.asarray(zip(*dat)) self.pol[k, i] = self.polyfit2d(x, y, z, orders=degree)
def __init__(self, xin, xout, **keywords): xin = np.asarray(xin) xout = np.asarray(xout) if xin.shape[-1] != 2: raise ValueError('The shape of the object plane coordinates should' ' be (npoints,ndims), where ndims is only impleme' 'nted for 2.') if xin.shape != xout.shape: raise ValueError('The object and image coordinates do not have the' ' same shape.') keywords['dtype'] = float Operator.__init__(self, **keywords) self.interp0 = interp.CloughTocher2DInterpolator(xin, xout[..., 0]) self.interp1 = interp.CloughTocher2DInterpolator(xin, xout[..., 1]) self.set_rule('I', lambda s: DistortionOperator(xout, xin))
def build(self,knot_vals): """Build Spline for the passed knot values @param [float] knot_vals Knot values on the mesh of self.knots_xx etc. """ #Check if logsline if self.logspline: if np.any(knot_vals<=0.): print "ERROR build: At least one knot member is ~<0, cannot apply log10" return False else: knot_vals = np.log10(knot_vals) #Check/correct if passed shape does not match if not np.array_equal(self.knots_shape, knot_vals.shape): #print "WARNING: passed knot array does not have the right shape" #print self.knots_shape, knot_vals.shape knot_vals = knot_vals.reshape(self.knots_shape) if self.built and np.array_equal(knot_vals, self.knot_vals): return False else: self.knot_vals = knot_vals #Add boundary knots" bknot_points = [] bvals_vals = [] for name in self.bknots: #~ print "Adding boundary", name bknot_points.append(self.bknots[name]["points"]) bvals_vals.append(self.bknots[name]["vals"]) #~ print np.array(bknot_points)[0],len(np.array(bknot_points)[0]) #~ print self.knot_points,len(self.knot_points) #~ print np.array(bvals_vals).flatten() #~ print self.knot_vals.flatten() if len(bknot_points)>0: spline_points = np.concatenate([self.knot_points,np.array(bknot_points)[0]]) spline_vals = np.concatenate([self.knot_vals.flatten(),np.array(bvals_vals).flatten()]) else: spline_points = self.knot_points spline_vals = self.knot_vals.flatten() #~ print spline_points,len(spline_points) #~ print spline_vals,len(spline_vals) if self.cloughtocher: self.spline2d = interp.CloughTocher2DInterpolator(spline_points,spline_vals,tol=0.1,maxiter=100,rescale=True) # else: pointsplit = np.hsplit(spline_points,2) #print "Build:" #print np.squeeze(pointsplit[0]),len(np.squeeze(pointsplit[0])) #print np.squeeze(pointsplit[1]),len(np.squeeze(pointsplit[1])) #print np.squeeze(spline_vals),len(np.squeeze(spline_vals)) self.spline2d = interp.interp2d(np.squeeze(pointsplit[0]), np.squeeze(pointsplit[1]),\ np.squeeze(spline_vals), kind='cubic',\ copy=False, bounds_error= False) # Interpolator from np self.built = True return True
def get_maps_from_file(path): x = np.genfromtxt(path, delimiter=',') zx = x[1:, 0] zy = x[1:, 1] xy = np.zeros((len(zx), 2)) xy[:, 0] = x[1:, 2] xy[:, 1] = x[1:, 4] assert (not np.isnan(xy.any())) assert (not np.isnan(zy.any())) assert (not np.isnan(zx.any())) xy[:, 0] = xy[:, 0] / x[0, 0] xy[:, 1] = xy[:, 1] / x[0, 1] mapx = interpolate.CloughTocher2DInterpolator(xy, zx) mapy = interpolate.CloughTocher2DInterpolator(xy, zy) return mapx, mapy
def create_cmaps(self, rot=0.): points = np.array([[0, 0], [1, 0], [0, 0.5], [1, 0.5], [0, 1], [1, 1]]) hue = (points[:, 1] * 1.5 + 3) / 6. + rot sat = np.array([1., 1., 1. / 3, 1. / 3, 1., 1.]) val = points[:, 0] hfunc = interpolate.LinearNDInterpolator(points, hue) sfunc = interpolate.CloughTocher2DInterpolator(points, sat) vfunc = interpolate.LinearNDInterpolator(points, val) return hfunc, sfunc, vfunc
def _cubic_interpolator(self, x, y): if self._dim == 1: ival = interpolate.interp1d(self._points[self._nanmask].flatten(), y[self._nanmask].flatten(), kind="cubic")(x)[:, np.newaxis] else: ival = interpolate.CloughTocher2DInterpolator( self._triangulation, y[self._nanmask])(x) return np.squeeze(ival)
def interpolate(self, shape=None): self.interpolator = interp.CloughTocher2DInterpolator( (self.anchors[:, 1], self.anchors[:, 0]), self.coarse_fit[0, ...].reshape((self.coarse_len**2, 1))) patch = self.interpolator(np.array(self.fine_ind)) if shape is None: self.patch = patch.reshape(self.fine_shape) else: self.patch = patch.reshape(shape)
def _interpolate_missing_data(data, mask, method='cubic'): """ Interpolate missing data as identified by the ``mask`` keyword. Parameters ---------- data : 2D `~numpy.ndarray` An array containing the 2D image. mask : 2D bool `~numpy.ndarray` A 2D booleen mask array with the same shape as the input ``data``, where a `True` value indicates the corresponding element of ``data`` is masked. The masked data points are those that will be interpolated. method : {'cubic', 'nearest'}, optional The method of used to interpolate the missing data: * ``'cubic'``: Masked data are interpolated using 2D cubic splines. This is the default. * ``'nearest'``: Masked data are interpolated using nearest-neighbor interpolation. Returns ------- data_interp : 2D `~numpy.ndarray` The interpolated 2D image. """ from scipy import interpolate data_interp = np.array(data, copy=True) if len(data_interp.shape) != 2: raise ValueError('data must be a 2D array.') if mask.shape != data.shape: raise ValueError('mask and data must have the same shape.') y, x = np.indices(data_interp.shape) xy = np.dstack((x[~mask].ravel(), y[~mask].ravel()))[0] z = data_interp[~mask].ravel() if method == 'nearest': interpol = interpolate.NearestNDInterpolator(xy, z) elif method == 'cubic': interpol = interpolate.CloughTocher2DInterpolator(xy, z) else: raise ValueError('Unsupported interpolation method.') xy_missing = np.dstack((x[mask].ravel(), y[mask].ravel()))[0] data_interp[mask] = interpol(xy_missing) return data_interp
def add_transformation(self, model): if model.is_affine(): new_model_matrix = model.get_matrix() # Need to add the transformation either to the pre_non_affine or the post_non_affine if self.non_affine_transform is None: cur_transformation = self.pre_non_affine_transform else: cur_transformation = self.post_non_affine_transform # Compute the new transformation (multiply from the left) new_transformation = np.dot(new_model_matrix, np.vstack((cur_transformation, [0., 0., 1.])))[:2] if self.non_affine_transform is None: self.pre_non_affine_transform = new_transformation else: self.post_non_affine_transform = new_transformation # Apply the model to each of the surrounding polygon locations self.surrounding_polygon = model.apply_special(self.surrounding_polygon) else: # Non-affine transformation self.non_affine_transform = model # TODO - need to see if this returns a sufficient bounding box for the reverse transformation # Find the new surrounding polygon locations # using a forward transformation from the boundaries of the source image to the destination boundary1 = np.array([[float(p), 0.] for p in np.arange(self.width)]) boundary2 = np.array([[float(p), float(self.height - 1)] for p in np.arange(self.width)]) boundary3 = np.array([[0., float(p)] for p in np.arange(self.height)]) boundary4 = np.array([[float(self.width - 1), float(p)] for p in np.arange(self.height)]) boundaries = np.concatenate((boundary1, boundary2, boundary3, boundary4)) boundaries = np.dot(self.pre_non_affine_transform[:2, :2], boundaries.T).T + self.pre_non_affine_transform[:, 2].reshape((1, 2)) src_points, dest_points = model.get_point_map() cubic_interpolator = spint.CloughTocher2DInterpolator(src_points, dest_points) self.surrounding_polygon = cubic_interpolator(boundaries) # Find the new surrounding polygon locations (using the destination points of the non affine transformation) #dest_points = model.get_point_map()[1] #hull = ConvexHull(dest_points) #self.surrounding_polygon = dest_points[hull.vertices] # Update bbox and shape according to the new borders self.bbox, self.shape = compute_bbox_and_shape(self.surrounding_polygon) # Remove any rendering self.already_rendered = False self.img = None
def test_interpolation(mesh): from scipy import interpolate x, y = mesh.x, mesh.y Z = np.exp(-x**2 - y**2) # We ensure interpolation points are within convex hull xi = np.random.uniform(0.1, 0.9, 10) yi = np.random.uniform(0.1, 0.9, 10) # Stripy zn1 = mesh.interpolate_nearest(xi, yi, Z) zl1, err = mesh.interpolate_linear(xi, yi, Z) zc1, err = mesh.interpolate_cubic(xi, yi, Z) # cKDTree tree = interpolate.NearestNDInterpolator((x, y), Z) zn2 = tree(xi, yi) # Qhull tri = interpolate.LinearNDInterpolator((x, y), Z, 0.0) zl2 = tri((xi, yi)) # Clough Tocher cti = interpolate.CloughTocher2DInterpolator(np.column_stack([x,y]),\ Z, tol=1e-10, maxiter=20) zc2 = cti((xi, yi)) zc2[np.isnan(zc2)] = 0.0 # Spline spl = interpolate.SmoothBivariateSpline(x, y, Z) zc3 = spl.ev(xi, yi) # Radial basis function rbf = interpolate.Rbf(x, y, Z) zc4 = rbf(xi, yi) print("squared residual in interpolation\n \ - nearest neighbour = {}\n \ - linear = {}\n \ - cubic (clough-tocher) = {}\n \ - cubic (spline) = {}\n \ - cubic (rbf) = {}" .format(((zn1 - zn2)**2).max(), \ ((zl1 - zl2)**2).max(), \ ((zc1 - zc2)**2).max(), \ ((zc1 - zc3)**2).max(), \ ((zc1 - zc4)**2).max(),) )
def test_derivative(mesh): from scipy import interpolate # Create a field to test derivatives x, y = mesh.x, mesh.y Z = np.exp(-x**2 - y**2) Zx = -2 * x * Z Zy = -2 * y * Z gradZ = np.hypot(Zx, Zy) # Stripy t = clock() Zx1, Zy1 = mesh.gradient(Z, nit=10, tol=1e-10) t1 = clock() - t gradZ1 = np.hypot(Zx1, Zy1) # Spline spl = interpolate.SmoothBivariateSpline(x, y, Z) t = clock() Zx2 = spl.ev(x, y, dx=1) Zy2 = spl.ev(x, y, dy=1) t2 = clock() - t gradZ2 = np.hypot(Zx2, Zy2) # Clough Tocher # This one is most similar to what is used in stripy t = clock() cti = interpolate.CloughTocher2DInterpolator(np.column_stack([x,y]),\ Z, tol=1e-10, maxiter=20) t3 = clock() - t Zx3 = cti.grad[:, :, 0].ravel() Zy3 = cti.grad[:, :, 1].ravel() gradZ3 = np.hypot(Zx3, Zy3) res1 = ((gradZ1 - gradZ)**2).max() res2 = ((gradZ2 - gradZ)**2).max() res3 = ((gradZ3 - gradZ)**2).max() print("squared error in first derivative\n \ - stripy = {} took {}s\n \ - spline = {} took {}s\n \ - cloughtocher = {} took {}s".format(res1, t1, res2, t2, res3, t3))
def Interpolate(videosFilePath, videoNames, pupilCenter, calibPointXY, startFrame, endFrame): pupilCenterCalib = pupilCenter[startFrame:endFrame] #interpoleFuncX = interp(pupilCenterCalib[:,0], calibPointXY[:,1]) #interpoleFuncY = interp1d(pupilCenterCalib[:,0], calibPointXY[:,1]) #eyeFocusX = interpoleFuncX(pupilCenter[:,0]) #eyeFocusY = interpoleFuncX(pupilCenter[:,1]) interpolator = interp.CloughTocher2DInterpolator( pupilCenter[startFrame:endFrame, :], calibPointXY) #eyeFocusCoords = (eyeFocusX,eyeFocusY) eyeFocusCoords = interpolator(pupilCenter) worldVidCap = cv2.VideoCapture(videosFilePath + '/' + videoNames[0] + '_f_c.mp4') frame_count = int(worldVidCap.get(cv2.CAP_PROP_FRAME_COUNT)) vidWidth = worldVidCap.get(cv2.CAP_PROP_FRAME_WIDTH) #Get video height vidHeight = worldVidCap.get(cv2.CAP_PROP_FRAME_HEIGHT) #Get video width vidLength = range(frame_count) outputVid = cv2.VideoWriter(videosFilePath + '/EyeFocusOnWorld.mp4', -1, 120, (int(vidWidth), int(vidHeight))) for jj in range(len(eyeFocusCoords)): if math.isnan(eyeFocusCoords[jj, 0]): success, image = worldVidCap.read() outputVid.write(image) else: success, image = worldVidCap.read() cv2.circle( image, (int(eyeFocusCoords[jj, 0]), int(eyeFocusCoords[jj, 1])), radius=10, color=[0, 255, 0], thickness=-1) outputVid.write(image) cv2.imshow('', image) cv2.waitKey(200) np.save(videosFilePath + '/EyeFocusWorld.npy', eyeFocusCoords) return eyeFocusCoords
def buildInterpolator2D(obs_arr, cosmo_params, method='Rbf'): '''Build an interpolator: input: obs_arr = (points, Nbin), where # of points = # of models cosmo_params = (points, Nparams), currently Nparams is hard-coded to be 3 (om,w,si8) output: spline_interps Usage: spline_interps[ibin](im, wm, sm) ''' m, s = cosmo_params.T spline_interps = list() for ibin in range(obs_arr.shape[-1]): model = obs_arr[:, ibin] if method == 'Rbf': iinterp = interpolate.Rbf(m, s, model) # elif method == 'linear': iinterp = interpolate.LinearNDInterpolator(cosmo_params, model) # elif method == 'clough': iinterp = interpolate.CloughTocher2DInterpolator( cosmo_params, model) # #iinterp = interpolate.Rbf(m, s, model) spline_interps.append(iinterp) #return spline_interps def interp_cosmo(params): '''Interpolate the powspec for certain param. Params: list of 3 parameters = (om, w, si8) Method: "multiquadric" for spline (default), and "GP" for Gaussian process. ''' mm, sm = params gen_ps = lambda ibin: spline_interps[ibin](mm, sm) ps_interp = array(map(gen_ps, range(obs_arr.shape[-1]))) ps_interp = ps_interp.reshape(-1, 1).squeeze() return ps_interp return interp_cosmo
def interpf(x, z, method=None, extrap=False, arrays=False): '''interpolate to find f, where z = f(*x) Input: x: an array of shape (npts, dim) or (npts,) z: an array of shape (npts,) method: string for kind of interpolator extrap: if True, extrapolate a bounding box (can reduce # of nans) arrays: if True, z = f(*x) is a numpy array; otherwise don't use arrays Output: interpolated function f, where z = f(*x) NOTE: if scipy is not installed, will use np.interp for 1D (non-rbf), or mystic's rbf otherwise. default method is 'nearest' for 1D and 'linear' otherwise. method can be one of ('rbf','linear','cubic', 'nearest','inverse','gaussian','multiquadric','quintic','thin_plate'). NOTE: if extrap is True, extrapolate using interpf with method='thin_plate' (or 'rbf' if scipy is not found). Alternately, any one of ('rbf', 'linear','cubic','nearest','inverse','gaussian','multiquadric', 'quintic','thin_plate') can be used. If extrap is a cost function z = f(x), then directly use it in the extrapolation. ''' #XXX: return f(*x) or f(x)? if arrays: _f, _fx = _to_array, _array else: _f, _fx = _to_nonarray, _nonarray x,z = extrapolate(x,z,method=extrap) x,z = _unique(x,z,sort=True) # avoid nan as first value #XXX: better choice than 'nearest'? if method is None: method = 'nearest' if x.ndim is 1 else 'linear' methods = dict(rbf=0, linear=1, nearest=2, cubic=3) functions = {0:'multiquadric', 1:'linear', 2:'nearest', 3:'cubic'} # also: ['thin_plate','inverse','gaussian','quintic'] kind = methods[method] if method in methods else None function = functions[kind] if (not kind is None) else method if kind is None: kind = 0 #XXX: or raise KeyError ? try: import scipy.interpolate as si except ImportError: if not kind is 0: # non-rbf if x.ndim is 1: # is 1D, so use np.interp import numpy as np return lambda xn: _fx(np.interp(xn, xp=x, fp=z)) kind = 0 # otherwise, utilize mystic's rbf si = _rbf if kind is 0: # 'rbf' import numpy as np return _f(si.Rbf(*np.vstack((x.T, z)), function=function, smooth=0)) elif x.ndim is 1: return _f(si.interp1d(x, z, fill_value='extrapolate', bounds_error=False, kind=method)) elif kind is 1: # 'linear' return _f(si.LinearNDInterpolator(x, z, rescale=False)) elif kind is 2: # 'nearest' return _f(si.NearestNDInterpolator(x, z, rescale=False)) #elif x.ndim is 1: # 'cubic' # return lambda xn: _fx(si.spline(x, z, xn)) return _f(si.CloughTocher2DInterpolator(x, z, rescale=False))
def __init__(self, coords, values, neighbors=3, dist_transform=2, **kwargs): super().__init__(coords, values, neighbors=neighbors, dist_transform=dist_transform) self.ct_interpolator = interpolate.CloughTocher2DInterpolator(self.tri, self.values, **kwargs)
def __call__(self, Zin): F = interpolate.CloughTocher2DInterpolator(self.XY, Zin) return F(self.XYout)
x = np.array(-500.* np.cos(u) * (5.3 - np.sin(u) + (1. + 0.138 * l) * np.cos(v))) y = np.array(750. * np.sin(u) * (5.5 - 2. * np.sin(u) + (0.9 + 0.114*l) * np.cos(v))) z = np.array(2500. * np.sin(u) + (663. + 114. * l) * np.sin(v - 0.13 * (np.pi-u))) return x,y,z du = (1.01*np.pi-(-0.016*np.pi))/max_u*spatial_resolution dv = (1.425*np.pi-(-0.23*np.pi))/max_v*spatial_resolution u = np.arange(-0.016*np.pi, 1.01*np.pi, du) v = np.arange(-0.23*np.pi, 1.425*np.pi, dv) u, v = np.meshgrid(u, v, indexing='ij') # for the middle of the granule cell layer: l = -1. s = surface (u, v, l) X = np.vstack((s[0].ravel(),s[1].ravel(),s[2].ravel())).T del s, u, v, l n_points = X.shape[0] n_neighbors = 30 n_components = 2 Y = manifold.LocallyLinearEmbedding(n_neighbors, n_components, eigen_solver='auto', method='modified').fit_transform(X) ip_surface = interpolate.CloughTocher2DInterpolator(Y, X)
d = 1e-5 #free energy landscape k=1 T=1 x1 = np.load(args.landscape) z = np.loadtxt(args.number) sum_z = np.sum(z) z = z/sum_z g = -k*T*np.log(z) x2 = x1[0:,:] # start from volume 0 to end if args.interpolate=='linear': Hfunc = interpolate.LinearNDInterpolator(x2, g) elif args.interpolate=='cubic': Hfunc = interpolate.CloughTocher2DInterpolator(x2, g) grid_z = Hfunc(grid_x, grid_y) # Main loop for nstep in range(nstepmax): # calculation of the x and y-components of the force, dVx and dVy respectively dVx=(Hfunc(xi+d,yi)-Hfunc(xi-d,yi))/(2*d) dVy=(Hfunc(xi,yi+d)-Hfunc(xi,yi-d))/(2*d) print("dV: ", np.mean(np.sqrt(dVx**2+dVy**2))) x0 = xi y0 = yi # string steps:
def __init__(self, config): # Shot data is mode-dependent mode = config["mode"] if mode not in config: raise ValueError( "parameters for mode '%s' missing from config file" % mode) config_mode = config[mode] # Generate shot data if "shot" in config_mode: shot = config_mode["shot"] aspect_ratio = config["aspect_ratio"] flux_ref = config_mode["flux"]["ref"] # TODO save and reload instead of always generating generateShotData(shot, aspect_ratio, flux_ref) # Load or pre-compute magnetic fields, ohmic power and magnetic energy filename = hashname(config) try: # Load pre-computed data set if it exists with h5py.File(filename, "r") as file: alpha = file["alpha"][:] lmbda0 = file["lambda_0"][:] flux = file["flux"][:] B_phi = file["B_phi"][:] B_theta = file["B_theta"][:] P_ohm = file["P_ohm"][:] U_mag = file["U_mag"][:] Ip = file["Ip"][:] F = file["F"][:] except: # Otherwise, pre-compute and save the results with h5py.File(filename, "w") as file: alpha, lmbda0, flux, B_phi, B_theta, P_ohm, U_mag, Ip, F = self.preCalc( config) file.create_dataset("alpha", data=alpha) file.create_dataset("lambda_0", data=lmbda0) file.create_dataset("flux", data=flux) file.create_dataset("B_phi", data=B_phi) file.create_dataset("B_theta", data=B_theta) file.create_dataset("P_ohm", data=P_ohm) file.create_dataset("U_mag", data=U_mag) file.create_dataset("Ip", data=Ip) file.create_dataset("F", data=F) # Make splines for magnetic fields, ohmic power and magnetic energy self.B_phi = sp.RectBivariateSpline(alpha, lmbda0, B_phi) self.B_theta = sp.RectBivariateSpline(alpha, lmbda0, B_theta) self.P_ohm = sp.RectBivariateSpline(alpha, lmbda0, P_ohm) self.U_mag = sp.RectBivariateSpline(alpha, lmbda0, U_mag) # One more spline fixed_alpha = 4.0 # FIXME: using hardcoded fixed alpha for now fixed_B_theta = sp.interp1d(alpha, B_theta, axis=0)(fixed_alpha) self.B_theta_to_lmbda0 = sp.CubicSpline(fixed_B_theta, lmbda0, bc_type="natural") # "translation" interpolators index_alpha = np.nonzero( alpha == fixed_alpha)[0][0] # FIXME: at least interpolate fixed_F = F[index_alpha, :, :] fixed_Ip = Ip[index_alpha, :, :] points = np.empty((fixed_F.size, 2)) lmbda0_values = np.empty(fixed_F.size) flux_values = np.empty(fixed_F.size) for (i, l0) in enumerate(lmbda0): for (j, fl) in enumerate(flux): k = i * flux.size + j points[k, :] = [fixed_F[i, j], fixed_Ip[i, j]] lmbda0_values[k] = l0 flux_values[k] = fl self.lmbda0 = sp.CloughTocher2DInterpolator(points, lmbda0_values, rescale=True) self.flux = sp.CloughTocher2DInterpolator(points, flux_values, rescale=True)
def piper(arrays, plottitle, use_color, fig=None, **kwargs): """Create a Piper plot: Args: arrays (ndarray, or see below): n x 8 ndarray with columns corresponding to Ca Mg Na K HCO3 CO3 Cl SO4 data. See below for a different format for this argument if you want to plot different subsets of data with different marker styles. plottitle (str): title of Piper plot use_color (bool): use background use_coloring of Piper plot fig (Figure): matplotlib Figure to use, one will be created if None If you would like to plot different sets of data e.g. from different aquifers with different marker styles, you can pass a list of tuples as the first arguments. The first item of each tuple should be an n x 8 ndarray, as usual. The second item should be a dictionary of keyword arguments to ``plt.scatter``. Any keyword arguments for ``plt.scatter`` that are in common to all the subsets can be passed to the ``piper()`` function directly. By default the markers are plotted with: ``plt.scatter(..., marker=".", color="k", alpha=1)``. Returns a dictionary with: if use_color = False: cat: [nx3] meq% of cations, order: Ca Mg Na+K an: [nx3] meq% of anions, order: HCO3+CO3 SO4 Cl if use_color = True: cat: [nx3] RGB triple cations an: [nx3] RGB triple anions diamond: [nx3] RGB triple central diamond """ kwargs["marker"] = kwargs.get("marker", ".") kwargs["alpha"] = kwargs.get("alpha", 1) kwargs["facecolor"] = kwargs.get("facecolor", "k") try: shp = arrays.shape if shp[1] == 8: arrays = [(arrays, {})] except: pass if fig is None: fig = plt.figure() # Basic shape of piper plot offset = 0.05 offsety = offset * np.tan(np.pi / 3) h = 0.5 * np.tan(np.pi / 3) ltriangle_x = np.array([0, 0.5, 1, 0]) ltriangle_y = np.array([0, h, 0, 0]) rtriangle_x = ltriangle_x + 2 * offset + 1 rtriangle_y = ltriangle_y diamond_x = np.array([0.5, 1, 1.5, 1, 0.5]) + offset diamond_y = h * (np.array([1, 2, 1, 0, 1])) + (offset * np.tan(np.pi / 3)) ax = fig.add_subplot(111, aspect='equal', frameon=False, xticks=[], yticks=[]) ax.plot(ltriangle_x, ltriangle_y, '-k') ax.plot(rtriangle_x, rtriangle_y, '-k') ax.plot(diamond_x, diamond_y, '-k') # labels and title plt.title(plottitle) plt.text(-offset, -offset, u'$Ca^{2+}$', horizontalalignment='left', verticalalignment='center') plt.text(0.5, h + offset, u'$Mg^{2+}$', horizontalalignment='center', verticalalignment='center') plt.text(1 + offset, -offset, u'$Na^+ + K^+$', horizontalalignment='right', verticalalignment='center') plt.text(1 + offset, -offset, u'$HCO_3^- + CO_3^{2-}$', horizontalalignment='left', verticalalignment='center') plt.text(1.5 + 2 * offset, h + offset, u'$SO_4^{2-}$', horizontalalignment='center', verticalalignment='center') plt.text(2 + 3 * offset, -offset, u'$Cl^-$', horizontalalignment='right', verticalalignment='center') # Convert chemistry into plot coordinates gmol = np.array([ 40.078, 24.305, 22.989768, 39.0983, 61.01714, 60.0092, 35.4527, 96.0636 ]) eqmol = np.array([2., 2., 1., 1., 1., 2., 1., 2.]) for dat_piper, plt_kws in arrays: n = dat_piper.shape[0] meqL = (dat_piper / gmol) * eqmol sumcat = np.sum(meqL[:, 0:4], axis=1) suman = np.sum(meqL[:, 4:8], axis=1) cat = np.zeros((n, 3)) an = np.zeros((n, 3)) cat[:, 0] = meqL[:, 0] / sumcat # Ca cat[:, 1] = meqL[:, 1] / sumcat # Mg cat[:, 2] = (meqL[:, 2] + meqL[:, 3]) / sumcat # Na+K an[:, 0] = (meqL[:, 4] + meqL[:, 5]) / suman # HCO3 + CO3 an[:, 2] = meqL[:, 6] / suman # Cl an[:, 1] = meqL[:, 7] / suman # SO4 # Convert into cartesian coordinates cat_x = 0.5 * (2 * cat[:, 2] + cat[:, 1]) cat_y = h * cat[:, 1] an_x = 1 + 2 * offset + 0.5 * (2 * an[:, 2] + an[:, 1]) an_y = h * an[:, 1] d_x = an_y / (4 * h) + 0.5 * an_x - cat_y / (4 * h) + 0.5 * cat_x d_y = 0.5 * an_y + h * an_x + 0.5 * cat_y - h * cat_x # plot data kws = dict(kwargs) kws.update(plt_kws) plt.scatter(cat_x, cat_y, **kws) plt.scatter(an_x, an_y, **{k: v for k, v in kws.items() if not k == "label"}) plt.scatter(d_x, d_y, **{k: v for k, v in kws.items() if not k == "label"}) # use_color coding Piper plot if use_color == False: # add density use_color bar if alphalevel < 1 if kwargs.get("alpha", 1) < 1.0: ax1 = fig.add_axes([0.75, 0.4, 0.01, 0.2]) cmap = plt.cm.gray_r norm = mpl.use_colors.Normalize(vmin=0, vmax=1 / kwargs["alpha"]) cb1 = mpl.use_colorbar.use_colorbarBase(ax1, cmap=cmap, norm=norm, orientation='vertical') cb1.set_label('Dot Density') return (dict(cat=cat, an=an)) else: # create empty grids to interpolate to x0 = 0.5 y0 = x0 * np.tan(np.pi / 6) X = np.reshape(np.repeat(np.linspace(0, 2 + 2 * offset, 1000), 1000), (1000, 1000), 'F') Y = np.reshape(np.repeat(np.linspace(0, 2 * h + offsety, 1000), 1000), (1000, 1000), 'C') H = np.nan * np.zeros_like(X) S = np.nan * np.zeros_like(X) V = np.nan * np.ones_like(X) A = np.nan * np.ones_like(X) # create masks for cation, anion triangle and upper and lower diamond ind_cat = np.logical_or(np.logical_and(X < 0.5, Y < 2 * h * X), np.logical_and(X > 0.5, Y < (2 * h * (1 - X)))) ind_an = np.logical_or( np.logical_and(X < 1.5 + (2 * offset), Y < 2 * h * (X - 1 - 2 * offset)), np.logical_and(X > 1.5 + (2 * offset), Y < (2 * h * (1 - (X - 1 - 2 * offset))))) ind_ld = np.logical_and( np.logical_or( np.logical_and(X < 1.0 + offset, Y > -2 * h * X + 2 * h * (1 + 2 * offset)), np.logical_and(X > 1.0 + offset, Y > 2 * h * X - 2 * h)), Y < h + offsety) ind_ud = np.logical_and( np.logical_or( np.logical_and(X < 1.0 + offset, Y < 2 * h * X), np.logical_and(X > 1.0 + offset, Y < -2 * h * X + 4 * h * (1 + offset))), Y > h + offsety) ind_d = np.logical_or(ind_ld == 1, ind_ud == 1) # Hue: convert x,y to polar coordinates # (angle between 0,0 to x0,y0 and x,y to x0,y0) H[ind_cat] = np.pi + np.arctan2(Y[ind_cat] - y0, X[ind_cat] - x0) H[ind_cat] = np.mod(H[ind_cat] - np.pi / 6, 2 * np.pi) H[ind_an] = np.pi + np.arctan2(Y[ind_an] - y0, X[ind_an] - (x0 + 1 + (2 * offset))) H[ind_an] = np.mod(H[ind_an] - np.pi / 6, 2 * np.pi) H[ind_d] = np.pi + np.arctan2(Y[ind_d] - (h + offsety), X[ind_d] - (1 + offset)) # Saturation: 1 at edge of triangle, 0 in the centre, # Clough Tocher interpolation, square root to reduce central white region xy_cat = np.array([[0.0, 0.0], [x0, h], [1.0, 0.0], [x0, y0]]) xy_an = np.array([[1 + (2 * offset), 0.0], [x0 + 1 + (2 * offset), h], [2 + (2 * offset), 0.0], [x0 + 1 + (2 * offset), y0]]) xy_d = np.array([[x0 + offset, h + offsety], [1 + offset, 2 * h + offsety], [x0 + 1 + offset, h + offsety], [1 + offset, offsety], [1 + offset, h + offsety]]) z_cat = np.array([1.0, 1.0, 1.0, 0.0]) z_an = np.array([1.0, 1.0, 1.0, 0.0]) z_d = np.array([1.0, 1.0, 1.0, 1.0, 0.0]) s_cat = interpolate.CloughTocher2DInterpolator(xy_cat, z_cat) s_an = interpolate.CloughTocher2DInterpolator(xy_an, z_an) s_d = interpolate.CloughTocher2DInterpolator(xy_d, z_d) S[ind_cat] = s_cat.__call__(X[ind_cat], Y[ind_cat]) S[ind_an] = s_an.__call__(X[ind_an], Y[ind_an]) S[ind_d] = s_d.__call__(X[ind_d], Y[ind_d]) # Value: 1 everywhere V[ind_cat] = 1.0 V[ind_an] = 1.0 V[ind_d] = 1.0 # Alpha: 1 everywhere A[ind_cat] = 1.0 A[ind_an] = 1.0 A[ind_d] = 1.0 # convert HSV to RGB R, G, B = hsvtorgb(H, S**0.5, V) RGBA = np.dstack((R, G, B, A)) # visualise plt.imshow(RGBA, origin='lower', aspect=1.0, extent=(0, 2 + 2 * offset, 0, 2 * h + offsety)) # calculate RGB triples for data points # hue hcat = np.pi + np.arctan2(cat_y - y0, cat_x - x0) hcat = np.mod(hcat - np.pi / 6, 2 * np.pi) han = np.pi + np.arctan2(an_y - y0, an_x - (x0 + 1 + (2 * offset))) han = np.mod(han - np.pi / 6, 2 * np.pi) hd = np.pi + np.arctan2(d_y - (h + offsety), d_x - (1 + offset)) # saturation scat = s_cat.__call__(cat_x, cat_y)**0.5 san = s_an.__call__(an_x, an_y)**0.5 sd = s_d.__call__(d_x, d_y)**0.5 # value v = np.ones_like(hd) # rgb cat = np.vstack((hsvtorgb(hcat, scat, v))).T an = np.vstack((hsvtorgb(han, san, v))).T d = np.vstack((hsvtorgb(hd, sd, v))).T return (dict(cat=cat, an=an, diamond=d))
#This here makes a grid for a given Re (alfa,S) and for each point sigma for case in caseList: # print case.alfa, case.Re for p in zip(case.S, case.sigma): alfa.append(float(case.alfa)) S.append(p[0]) sig.append(p[1]) p = [] #this grid (alfa,S) is stored in p, and used to find an interpolant for pair in zip(alfa, S): p.append([pair[0], pair[1]]) if InterType == 1: interp = interpolate.LinearNDInterpolator(p, sig) elif InterType == 2: interp = interpolate.CloughTocher2DInterpolator(p, sig) else: raise "Unknown Interpolation type" if with3D: Anew = np.linspace(min(alfa), max(alfa), num=200, endpoint=True) Snew = np.linspace(min(S), max(S), num=200, endpoint=True) Anew, Snew = np.meshgrid(Anew, Snew) zz = interp(Anew, Snew) fig = plt.figure() ax = fig.gca(projection='3d') ax.set_xlabel('alpha') ax.set_ylabel('S') ax.set_zlabel('Sigma') plt.title('Re=' + str(caseList[0].Re))
def piper(dat_piper, plottitle, alphalevel, color): ''' Create a Piper plot INPUT: dat_piper: [nx8] matrix, chemical analysis in mg/L order: Ca Mg Na K HCO3 CO3 Cl SO4 plottitle: string with title of Piper plot alphalevel: transparency level of points. If 1, points are opaque color: boolean, use background coloring of Piper plot OUTPUT: figure with piperplot dictionary with: if color = False: cat: [nx3] meq% of cations, order: Ca Mg Na+K an: [nx3] meq% of anions, order: HCO3+CO3 SO4 Cl if color = True: cat: [nx3] RGB triple cations an: [nx3] RGB triple anions diamond: [nx3] RGB triple central diamond ''' # Basic shape of piper plot offset = 0.05 offsety = offset * np.tan(np.pi / 3) h = 0.5 * np.tan(np.pi / 3) ltriangle_x = np.array([0, 0.5, 1, 0]) ltriangle_y = np.array([0, h, 0, 0]) rtriangle_x = ltriangle_x + 2 * offset + 1 rtriangle_y = ltriangle_y diamond_x = np.array([0.5, 1, 1.5, 1, 0.5]) + offset diamond_y = h * (np.array([1, 2, 1, 0, 1])) + (offset * np.tan(np.pi / 3)) fig = plt.figure() ax = fig.add_subplot(111, aspect='equal', frameon=False, xticks=[], yticks=[]) ax.plot(ltriangle_x, ltriangle_y, '-k') ax.plot(rtriangle_x, rtriangle_y, '-k') ax.plot(diamond_x, diamond_y, '-k') # labels and title plt.title(plottitle) plt.text(-offset, -offset, u'$Ca^{2+}$', horizontalalignment='left', verticalalignment='center') plt.text(0.5, h + offset, u'$Mg^{2+}$', horizontalalignment='center', verticalalignment='center') plt.text(1 + offset, -offset, u'$Na^+ + K^+$', horizontalalignment='right', verticalalignment='center') plt.text(1 + offset, -offset, u'$HCO_3^- + CO_3^{2-}$', horizontalalignment='left', verticalalignment='center') plt.text(1.5 + 2 * offset, h + offset, u'$SO_4^{2-}$', horizontalalignment='center', verticalalignment='center') plt.text(2 + 3 * offset, -offset, u'$Cl^-$', horizontalalignment='right', verticalalignment='center') # Convert chemistry into plot coordinates gmol = np.array([ 40.078, 24.305, 22.989768, 39.0983, 61.01714, 60.0092, 35.4527, 96.0636 ]) eqmol = np.array([2., 2., 1., 1., 1., 2., 1., 2.]) n = dat_piper.shape[0] meqL = (dat_piper / gmol) * eqmol sumcat = np.sum(meqL[:, 0:4], axis=1) suman = np.sum(meqL[:, 4:8], axis=1) cat = np.zeros((n, 3)) an = np.zeros((n, 3)) cat[:, 0] = meqL[:, 0] / sumcat # Ca cat[:, 1] = meqL[:, 1] / sumcat # Mg cat[:, 2] = (meqL[:, 2] + meqL[:, 3]) / sumcat # Na+K an[:, 0] = (meqL[:, 4] + meqL[:, 5]) / suman # HCO3 + CO3 an[:, 2] = meqL[:, 6] / suman # Cl an[:, 1] = meqL[:, 7] / suman # SO4 # Convert into cartesian coordinates cat_x = 0.5 * (2 * cat[:, 2] + cat[:, 1]) cat_y = h * cat[:, 1] an_x = 1 + 2 * offset + 0.5 * (2 * an[:, 2] + an[:, 1]) an_y = h * an[:, 1] d_x = an_y / (4 * h) + 0.5 * an_x - cat_y / (4 * h) + 0.5 * cat_x d_y = 0.5 * an_y + h * an_x + 0.5 * cat_y - h * cat_x # plot data plt.plot(cat_x, cat_y, '.k', alpha=alphalevel) plt.plot(an_x, an_y, '.k', alpha=alphalevel) plt.plot(d_x, d_y, '.k', alpha=alphalevel) # color coding Piper plot if color == False: # add density color bar if alphalevel < 1 if alphalevel < 1.0: ax1 = fig.add_axes([0.75, 0.4, 0.01, 0.2]) cmap = plt.cm.gray_r norm = mpl.colors.Normalize(vmin=0, vmax=1 / alphalevel) cb1 = mpl.colorbar.ColorbarBase(ax1, cmap=cmap, norm=norm, orientation='vertical') cb1.set_label('Dot Density') return (dict(cat=cat, an=an)) else: # create empty grids to interpolate to x0 = 0.5 y0 = x0 * np.tan(np.pi / 6) X = np.reshape(np.repeat(np.linspace(0, 2 + 2 * offset, 1000), 1000), (1000, 1000), 'F') Y = np.reshape(np.repeat(np.linspace(0, 2 * h + offsety, 1000), 1000), (1000, 1000), 'C') H = np.nan * np.zeros_like(X) S = np.nan * np.zeros_like(X) V = np.nan * np.ones_like(X) A = np.nan * np.ones_like(X) # create masks for cation, anion triangle and upper and lower diamond ind_cat = np.logical_or(np.logical_and(X < 0.5, Y < 2 * h * X), np.logical_and(X > 0.5, Y < (2 * h * (1 - X)))) ind_an = np.logical_or( np.logical_and(X < 1.5 + (2 * offset), Y < 2 * h * (X - 1 - 2 * offset)), np.logical_and(X > 1.5 + (2 * offset), Y < (2 * h * (1 - (X - 1 - 2 * offset))))) ind_ld = np.logical_and( np.logical_or( np.logical_and(X < 1.0 + offset, Y > -2 * h * X + 2 * h * (1 + 2 * offset)), np.logical_and(X > 1.0 + offset, Y > 2 * h * X - 2 * h)), Y < h + offsety) ind_ud = np.logical_and( np.logical_or( np.logical_and(X < 1.0 + offset, Y < 2 * h * X), np.logical_and(X > 1.0 + offset, Y < -2 * h * X + 4 * h * (1 + offset))), Y > h + offsety) ind_d = np.logical_or(ind_ld == 1, ind_ud == 1) # Hue: convert x,y to polar coordinates # (angle between 0,0 to x0,y0 and x,y to x0,y0) H[ind_cat] = np.pi + np.arctan2(Y[ind_cat] - y0, X[ind_cat] - x0) H[ind_cat] = np.mod(H[ind_cat] - np.pi / 6, 2 * np.pi) H[ind_an] = np.pi + np.arctan2(Y[ind_an] - y0, X[ind_an] - (x0 + 1 + (2 * offset))) H[ind_an] = np.mod(H[ind_an] - np.pi / 6, 2 * np.pi) H[ind_d] = np.pi + np.arctan2(Y[ind_d] - (h + offsety), X[ind_d] - (1 + offset)) # Saturation: 1 at edge of triangle, 0 in the centre, # Clough Tocher interpolation, square root to reduce central white region xy_cat = np.array([[0.0, 0.0], [x0, h], [1.0, 0.0], [x0, y0]]) xy_an = np.array([[1 + (2 * offset), 0.0], [x0 + 1 + (2 * offset), h], [2 + (2 * offset), 0.0], [x0 + 1 + (2 * offset), y0]]) xy_d = np.array([[x0 + offset, h + offsety], [1 + offset, 2 * h + offsety], [x0 + 1 + offset, h + offsety], [1 + offset, offsety], [1 + offset, h + offsety]]) z_cat = np.array([1.0, 1.0, 1.0, 0.0]) z_an = np.array([1.0, 1.0, 1.0, 0.0]) z_d = np.array([1.0, 1.0, 1.0, 1.0, 0.0]) s_cat = interpolate.CloughTocher2DInterpolator(xy_cat, z_cat) s_an = interpolate.CloughTocher2DInterpolator(xy_an, z_an) s_d = interpolate.CloughTocher2DInterpolator(xy_d, z_d) S[ind_cat] = s_cat.__call__(X[ind_cat], Y[ind_cat]) S[ind_an] = s_an.__call__(X[ind_an], Y[ind_an]) S[ind_d] = s_d.__call__(X[ind_d], Y[ind_d]) # Value: 1 everywhere V[ind_cat] = 1.0 V[ind_an] = 1.0 V[ind_d] = 1.0 # Alpha: 1 everywhere A[ind_cat] = 1.0 A[ind_an] = 1.0 A[ind_d] = 1.0 # convert HSV to RGB R, G, B = hsvtorgb(H, S**0.5, V) RGBA = np.dstack((R, G, B, A)) # visualise plt.imshow(RGBA, origin='lower', aspect=1.0, extent=(0, 2 + 2 * offset, 0, 2 * h + offsety)) # calculate RGB triples for data points # hue hcat = np.pi + np.arctan2(cat_y - y0, cat_x - x0) hcat = np.mod(hcat - np.pi / 6, 2 * np.pi) han = np.pi + np.arctan2(an_y - y0, an_x - (x0 + 1 + (2 * offset))) han = np.mod(han - np.pi / 6, 2 * np.pi) hd = np.pi + np.arctan2(d_y - (h + offsety), d_x - (1 + offset)) # saturation scat = s_cat.__call__(cat_x, cat_y)**0.5 san = s_an.__call__(an_x, an_y)**0.5 sd = s_d.__call__(d_x, d_y)**0.5 # value v = np.ones_like(hd) # rgb cat = np.vstack((hsvtorgb(hcat, scat, v))).T an = np.vstack((hsvtorgb(han, san, v))).T d = np.vstack((hsvtorgb(hd, sd, v))).T return (dict(cat=cat, an=an, diamond=d))
# importar funciones de interpolación de la libreria de matemática avanzada from scipy import interpolate # Interpolación en una variable funcion = interpolate.interp1d([x1, x2, xN], [y1, y2, yN], 'zero') # Interpolación constante con Spline (Retorna valor de "y" anterior mas cercano) (Minimo 1 punto) funcion = interpolate.interp1d([x1, x2, xN], [y1, y2, yN], 'previous') # Interpolación constante (Retorna valor de "y" anterior mas cercano) (Minimo 1 punto) funcion = interpolate.interp1d([x1, x2, xN], [y1, y2, yN], 'next') # Interpolación constante (Retorna valor de "y" posterior mas cercano) (Minimo 1 punto) funcion = interpolate.interp1d([x1, x2, xN], [y1, y2, yN], 'nearest') # Interpolación del vecino más cercano (Retorna valor de "y" mas cercano) (Minimo 1 punto) funcion = interpolate.interp1d([x1, x2, xN], [y1, y2, yN], 'linear') # Interpolación lineal (Minimo 2 puntos) funcion = interpolate.interp1d([x1, x2, xN], [y1, y2, yN], 'slinear') # Interpolación lineal con Spline (Minimo 2 puntos) funcion = interpolate.interp1d([x1, x2, xN], [y1, y2, yN], 'quadratic') # Interpolación cuadratica con Spline (Minimo 3 puntos) funcion = interpolate.interp1d([x1, x2, xN], [y1, y2, yN], 'cubic') # Interpolación cubica con Spline (Minimo 4 puntos) # Interpolación multivariable x_vals = [[x11,x12,x1M],[x21,x22,x2M],[xN1,xN2,xNM]] # Valores independientes dados y_vals = [y1, y2, yN] # Valores dependientes dados malla = tuple(np.mgrid[x1_o:x1_f:x1_tam, x2_o:x2_f:x2_tam, xN_o:xN_f:xN_tam]) # Malla de valores a evaluar [x1 inicial:x1 final:n° puntos en x1, x2 inicial:x2 final:n° puntos en x2, xN inicial:xN final:n° puntos en xN] array = interpolate.griddata(x_vals, y_vals, malla, method='nearest') # Evaluación de la malla por Interpolación del vecino más cercano array = interpolate.griddata(x_vals, y_vals, malla, method='linear') # Evaluación de la malla por Interpolación lineal array = interpolate.griddata(x_vals, y_vals, malla, method='cubic') # Evaluación de la malla por Interpolación cubica funcion = interpolate.NearestNDInterpolator(x_vals, y_vals) # Interpolación del vecino más cercano (Retorna valor de "y" mas cercano) (Minimo 1 punto) funcion = interpolate.LinearNDInterpolator(x_vals, y_vals) # Interpolación lineal (Minimo 2 puntos) funcion = interpolate.CloughTocher2DInterpolator(x_vals, y_vals) # Interpolación cubica para funciones de 2 variables (Minimo 2 puntos)
def list_plot3d_tuples(v, interpolation_type, texture, **kwds): r""" A 3-dimensional plot of a surface defined by the list `v` of points in 3-dimensional space. INPUT: - ``v`` - something that defines a set of points in 3 space, for example: - a matrix This will be if using an interpolation type other than 'linear', or if using ``num_points`` with 'linear'; otherwise see :func:`list_plot3d_matrix`. - a list of 3-tuples - a list of lists (all of the same length, under same conditions as a matrix) - ``texture`` - (default: "automatic", a solid light blue) OPTIONAL KEYWORDS: - ``interpolation_type`` - 'linear', 'clough' (CloughTocher2D), 'spline' 'linear' will perform linear interpolation The option 'clough' will interpolate by using a piecewise cubic interpolating Bezier polynomial on each triangle, using a Clough-Tocher scheme. The interpolant is guaranteed to be continuously differentiable. The option 'spline' interpolates using a bivariate B-spline. When v is a matrix the default is to use linear interpolation, when v is a list of points the default is 'clough'. - ``degree`` - an integer between 1 and 5, controls the degree of spline used for spline interpolation. For data that is highly oscillatory use higher values - ``point_list`` - If point_list=True is passed, then if the array is a list of lists of length three, it will be treated as an array of points rather than a `3\times n` array. - ``num_points`` - Number of points to sample interpolating function in each direction. By default for an `n\times n` array this is `n`. - ``**kwds`` - all other arguments are passed to the surface function OUTPUT: a 3d plot EXAMPLES: All of these use this function; see :func:`list_plot3d` for other list plots:: sage: pi = float(pi) sage: m = matrix(RDF, 6, [sin(i^2 + j^2) for i in [0,pi/5,..,pi] for j in [0,pi/5,..,pi]]) sage: list_plot3d(m, texture='yellow', interpolation_type='linear', num_points=5) # indirect doctest Graphics3d Object :: sage: list_plot3d(m, texture='yellow', interpolation_type='spline', frame_aspect_ratio=[1, 1, 1/3]) Graphics3d Object :: sage: show(list_plot3d([[1, 1, 1], [1, 2, 1], [0, 1, 3], [1, 0, 4]], point_list=True)) :: sage: list_plot3d([(1, 2, 3), (0, 1, 3), (2, 1, 4), (1, 0, -2)], texture='yellow', num_points=50) # long time Graphics3d Object """ from matplotlib import tri import numpy from random import random from scipy import interpolate from .plot3d import plot3d if len(v) < 3: raise ValueError( "We need at least 3 points to perform the interpolation") x = [float(p[0]) for p in v] y = [float(p[1]) for p in v] z = [float(p[2]) for p in v] # If the (x,y)-coordinates lie in a one-dimensional subspace, the # matplotlib Delaunay code segfaults. Therefore, we compute the # correlation of the x- and y-coordinates and add small random # noise to avoid the problem if needed. corr_matrix = numpy.corrcoef(x, y) if corr_matrix[0, 1] > 0.9 or corr_matrix[0, 1] < -0.9: ep = float(.000001) x = [float(p[0]) + random() * ep for p in v] y = [float(p[1]) + random() * ep for p in v] # If the list of data points has two points with the exact same # (x,y)-coordinate but different z-coordinates, then we sometimes # get segfaults. The following block checks for this and raises # an exception if this is the case. # We also remove duplicate points (which matplotlib can't handle). # Alternatively, the code in the if block above which adds random # error could be applied to perturb the points. drop_list = [] nb_points = len(x) for i in range(nb_points): for j in range(i + 1, nb_points): if x[i] == x[j] and y[i] == y[j]: if z[i] != z[j]: raise ValueError( "Two points with same x,y coordinates and different z coordinates were given. Interpolation cannot handle this." ) elif z[i] == z[j]: drop_list.append(j) x = [x[i] for i in range(nb_points) if i not in drop_list] y = [y[i] for i in range(nb_points) if i not in drop_list] z = [z[i] for i in range(nb_points) if i not in drop_list] xmin = float(min(x)) xmax = float(max(x)) ymin = float(min(y)) ymax = float(max(y)) num_points = kwds['num_points'] if 'num_points' in kwds else int( 4 * numpy.sqrt(len(x))) #arbitrary choice - assuming more or less a nxn grid of points # x should have n^2 entries. We sample 4 times that many points. if interpolation_type == 'linear': T = tri.Triangulation(x, y) f = tri.LinearTriInterpolator(T, z) j = numpy.complex(0, 1) from .parametric_surface import ParametricSurface def g(x, y): z = f(x, y) return (x, y, z) G = ParametricSurface(g, (list(numpy.r_[xmin:xmax:num_points * j]), list(numpy.r_[ymin:ymax:num_points * j])), texture=texture, **kwds) G._set_extra_kwds(kwds) return G if interpolation_type == 'clough' or interpolation_type == 'default': points = [[x[i], y[i]] for i in range(len(x))] j = numpy.complex(0, 1) f = interpolate.CloughTocher2DInterpolator(points, z) from .parametric_surface import ParametricSurface def g(x, y): z = f([x, y]) return (x, y, z) G = ParametricSurface(g, (list(numpy.r_[xmin:xmax:num_points * j]), list(numpy.r_[ymin:ymax:num_points * j])), texture=texture, **kwds) G._set_extra_kwds(kwds) return G if interpolation_type == 'spline': kx = kwds['kx'] if 'kx' in kwds else 3 ky = kwds['ky'] if 'ky' in kwds else 3 if 'degree' in kwds: kx = kwds['degree'] ky = kwds['degree'] s = kwds['smoothing'] if 'smoothing' in kwds else len(x) - numpy.sqrt( 2 * len(x)) s = interpolate.bisplrep(x, y, z, [int(1)] * len(x), xmin, xmax, ymin, ymax, kx=kx, ky=ky, s=s) f = lambda x, y: interpolate.bisplev(x, y, s) return plot3d(f, (xmin, xmax), (ymin, ymax), texture=texture, plot_points=[num_points, num_points], **kwds)
def piper(array, alphalevel=1, color=True, show=True, save=False, fname=None, figsize=(4, 4)): r""" Create a Piper plot using the code by Peeters, (2014). Args: :param array: A one or two dimensional array containing in mM/L in the \ order of 'Ca', 'Mg', 'Na', 'K', 'HCO3', 'CO3', 'Cl', 'SO4'. :param alphalevel: transparency level of points. If 1, points are opaque :param color: boolean, use background coloring of Piper plot default True :param show: If True shows plot else returns plot object. :param save: Save the plot default is False :param fname: Filename default is none :param figsize: Figure size tuple default (8, 3) :return: Piperplot Code from https://github.com/inkenbrandt/Peeters_Piper/blob/master/peeter_\ piper.py: Citation: @article {GWAT:GWAT12118, author = {Peeters, Luk}, title = {A Background Color Scheme for Piper Plots to Spatially Visualize \ Hydrochemical Patterns}, journal = {Groundwater}, volume = {52}, number = {1}, publisher = {Blackwell Publishing Ltd}, issn = {1745-6584}, url = {http://dx.doi.org/10.1111/gwat.12118}, doi = {10.1111/gwat.12118}, pages = {2--6}, year = {2014}, } """ dat_piper = array ndims = len(dat_piper.shape) if ndims == 1: dat_piper = np.concatenate((dat_piper, dat_piper)).reshape(2, 8) def hsvtorgb(H, S, V): # conversion (from http://en.wikipedia.org/wiki/HSL_and_HSV) C = V * S Hs = H / (np.pi / 3) X = C * (1 - np.abs(np.mod(Hs, 2.0 * np.ones_like(Hs)) - 1)) N = np.zeros_like(H) # create empty RGB matrices R = np.zeros_like(H) B = np.zeros_like(H) G = np.zeros_like(H) # assign values h = np.floor(Hs) # h=0 R[h == 0] = C[h == 0] G[h == 0] = X[h == 0] B[h == 0] = N[h == 0] # h=1 R[h == 1] = X[h == 1] G[h == 1] = C[h == 1] B[h == 1] = N[h == 1] # h=2 R[h == 2] = N[h == 2] G[h == 2] = C[h == 2] B[h == 2] = X[h == 2] # h=3 R[h == 3] = N[h == 3] G[h == 3] = X[h == 3] B[h == 3] = C[h == 3] # h=4 R[h == 4] = X[h == 4] G[h == 4] = N[h == 4] B[h == 4] = C[h == 4] # h=5 R[h == 5] = C[h == 5] G[h == 5] = N[h == 5] B[h == 5] = X[h == 5] # match values m = V - C R = R + m G = G + m B = B + m return (R, G, B) # Basic shape of piper plot offset = 0.15 offsety = offset * np.tan(np.pi / 3) h = 0.5 * np.tan(np.pi / 3) ltriangle_x = np.array([0, 0.5, 1, 0]) ltriangle_y = np.array([0, h, 0, 0]) rtriangle_x = ltriangle_x + 2 * offset + 1 rtriangle_y = ltriangle_y diamond_x = np.array([0.5, 1, 1.5, 1, 0.5]) + offset diamond_y = h * (np.array([1, 2, 1, 0, 1])) + (offset * np.tan(np.pi / 3)) fig = plt.figure(figsize=figsize) ax = fig.add_subplot(111, aspect='equal', frameon=False, xticks=[], yticks=[]) ax.plot(ltriangle_x, ltriangle_y, '-k') ax.plot(rtriangle_x, rtriangle_y, '-k') ax.plot(diamond_x, diamond_y, '-k') # labels and title plt.text(-offset, -offset, '$Ca^{2+}$', horizontalalignment='left', verticalalignment='center') plt.text(0.5, h + offset, '$Mg^{2+}$', horizontalalignment='center', verticalalignment='center') plt.text(1 + offset, -offset, '$Na^+ + K^+$', horizontalalignment='right', verticalalignment='center') plt.text(1 + offset, -offset, '$HCO_3^- + CO_3^{2-}$', horizontalalignment='left', verticalalignment='center') plt.text(1.5 + 2 * offset, h + offset, '$SO_4^{2-}$', horizontalalignment='center', verticalalignment='center') plt.text(2 + 3 * offset, -offset, '$Cl^-$', horizontalalignment='right', verticalalignment='center') # Convert chemistry into plot coordinates gmol = np.array([ 40.078, 24.305, 22.989768, 39.0983, 61.01714, 60.0092, 35.4527, 96.0636 ]) eqmol = np.array([2., 2., 1., 1., 1., 2., 1., 2.]) n = dat_piper.shape[0] meqL = (dat_piper / gmol) * eqmol sumcat = np.sum(meqL[:, 0:4], axis=1) suman = np.sum(meqL[:, 4:8], axis=1) cat = np.zeros((n, 3)) an = np.zeros((n, 3)) cat[:, 0] = meqL[:, 0] / sumcat # Ca cat[:, 1] = meqL[:, 1] / sumcat # Mg cat[:, 2] = (meqL[:, 2] + meqL[:, 3]) / sumcat # Na+K an[:, 0] = (meqL[:, 4] + meqL[:, 5]) / suman # HCO3 + CO3 an[:, 2] = meqL[:, 6] / suman # Cl an[:, 1] = meqL[:, 7] / suman # SO4 # Convert into cartesian coordinates cat_x = 0.5 * (2 * cat[:, 2] + cat[:, 1]) cat_y = h * cat[:, 1] an_x = 1 + 2 * offset + 0.5 * (2 * an[:, 2] + an[:, 1]) an_y = h * an[:, 1] d_x = an_y / (4 * h) + 0.5 * an_x - cat_y / (4 * h) + 0.5 * cat_x d_y = 0.5 * an_y + h * an_x + 0.5 * cat_y - h * cat_x # plot data plt.plot(cat_x, cat_y, '.k', alpha=alphalevel) plt.plot(an_x, an_y, '.k', alpha=alphalevel) plt.plot(d_x, d_y, '.k', alpha=alphalevel) # color coding Piper plot if color is False: # add density color bar if alphalevel < 1 if alphalevel < 1.0: ax1 = fig.add_axes([0.75, 0.4, 0.01, 0.2]) cmap = plt.cm.gray_r norm = mpl.colors.Normalize(vmin=0, vmax=1 / alphalevel) cb1 = mpl.colorbar.ColorbarBase(ax1, cmap=cmap, norm=norm, orientation='vertical') cb1.set_label('Dot Density') return (dict(cat=cat, an=an)) else: import scipy.interpolate as interpolate # create empty grids to interpolate to x0 = 0.5 y0 = x0 * np.tan(np.pi / 6) X = np.reshape(np.repeat(np.linspace(0, 2 + 2 * offset, 1000), 1000), (1000, 1000), 'F') Y = np.reshape(np.repeat(np.linspace(0, 2 * h + offsety, 1000), 1000), (1000, 1000), 'C') H = np.nan * np.zeros_like(X) S = np.nan * np.zeros_like(X) V = np.nan * np.ones_like(X) A = np.nan * np.ones_like(X) # create masks for cation, anion triangle and upper and lower diamond ind_cat = np.logical_or(np.logical_and(X < 0.5, Y < 2 * h * X), np.logical_and(X > 0.5, Y < (2 * h * (1 - X)))) ind_an = np.logical_or( np.logical_and(X < 1.5 + (2 * offset), Y < 2 * h * (X - 1 - 2 * offset)), np.logical_and(X > 1.5 + (2 * offset), Y < (2 * h * (1 - (X - 1 - 2 * offset))))) ind_ld = np.logical_and( np.logical_or( np.logical_and(X < 1.0 + offset, Y > -2 * h * X + 2 * h * (1 + 2 * offset)), np.logical_and(X > 1.0 + offset, Y > 2 * h * X - 2 * h)), Y < h + offsety) ind_ud = np.logical_and( np.logical_or( np.logical_and(X < 1.0 + offset, Y < 2 * h * X), np.logical_and(X > 1.0 + offset, Y < -2 * h * X + 4 * h * (1 + offset))), Y > h + offsety) ind_d = np.logical_or(ind_ld == 1, ind_ud == 1) # Hue: convert x,y to polar coordinates # (angle between 0,0 to x0,y0 and x,y to x0,y0) H[ind_cat] = np.pi + np.arctan2(Y[ind_cat] - y0, X[ind_cat] - x0) H[ind_cat] = np.mod(H[ind_cat] - np.pi / 6, 2 * np.pi) H[ind_an] = np.pi + np.arctan2(Y[ind_an] - y0, X[ind_an] - (x0 + 1 + (2 * offset))) H[ind_an] = np.mod(H[ind_an] - np.pi / 6, 2 * np.pi) H[ind_d] = np.pi + np.arctan2(Y[ind_d] - (h + offsety), X[ind_d] - (1 + offset)) # Saturation: 1 at edge of triangle, 0 in the centre, # Clough Tocher interpolation, square root to reduce central region xy_cat = np.array([[0.0, 0.0], [x0, h], [1.0, 0.0], [x0, y0]]) xy_an = np.array([[1 + (2 * offset), 0.0], [x0 + 1 + (2 * offset), h], [2 + (2 * offset), 0.0], [x0 + 1 + (2 * offset), y0]]) xy_d = np.array([[x0 + offset, h + offsety], [1 + offset, 2 * h + offsety], [x0 + 1 + offset, h + offsety], [1 + offset, offsety], [1 + offset, h + offsety]]) z_cat = np.array([1.0, 1.0, 1.0, 0.0]) z_an = np.array([1.0, 1.0, 1.0, 0.0]) z_d = np.array([1.0, 1.0, 1.0, 1.0, 0.0]) s_cat = interpolate.CloughTocher2DInterpolator(xy_cat, z_cat) s_an = interpolate.CloughTocher2DInterpolator(xy_an, z_an) s_d = interpolate.CloughTocher2DInterpolator(xy_d, z_d) S[ind_cat] = s_cat.__call__(X[ind_cat], Y[ind_cat]) S[ind_an] = s_an.__call__(X[ind_an], Y[ind_an]) S[ind_d] = s_d.__call__(X[ind_d], Y[ind_d]) # Value: 1 everywhere V[ind_cat] = 1.0 V[ind_an] = 1.0 V[ind_d] = 1.0 # Alpha: 1 everywhere A[ind_cat] = 1.0 A[ind_an] = 1.0 A[ind_d] = 1.0 # convert HSV to RGB R, G, B = hsvtorgb(H, S**0.5, V) RGBA = np.dstack((R, G, B, A)) # visualise plt.imshow(RGBA, origin='lower', aspect=1.0, extent=(0, 2 + 2 * offset, 0, 2 * h + offsety)) # calculate RGB triples for data points # hue hcat = np.pi + np.arctan2(cat_y - y0, cat_x - x0) hcat = np.mod(hcat - np.pi / 6, 2 * np.pi) han = np.pi + np.arctan2(an_y - y0, an_x - (x0 + 1 + (2 * offset))) han = np.mod(han - np.pi / 6, 2 * np.pi) hd = np.pi + np.arctan2(d_y - (h + offsety), d_x - (1 + offset)) # saturation scat = s_cat.__call__(cat_x, cat_y)**0.5 san = s_an.__call__(an_x, an_y)**0.5 # value v = np.ones_like(hd) # rgb cat = np.vstack((hsvtorgb(hcat, scat, v))).T an = np.vstack((hsvtorgb(han, san, v))).T module_io.output(fig, show, save, fname)
def __init__(self, x, y, z): super().__init__(x, y) self.z = z points = np.concatenate( (np.expand_dims(x, axis=1), np.expand_dims(y, axis=1)), axis=1) self.CTFunction = interpolate.CloughTocher2DInterpolator(points, z)
def piper(dat_piper, plottitle, alphalevel, color): ''' Create a Piper plot INPUT: dat_piper: [nx8] matrix, chemical analysis in mg/L order: Ca Mg Na K HCO3 CO3 Cl SO4 plottitle: string with title of Piper plot alphalevel: transparency level of points. If 1, points are opaque color: boolean, use background coloring of Piper plot OUTPUT: figure with piperplot dictionary with: if color = False: cat: [nx3] meq% of cations, order: Ca Mg Na+K an: [nx3] meq% of anions, order: HCO3+CO3 SO4 Cl if color = True: cat: [nx3] RGB triple cations an: [nx3] RGB triple anions diamond: [nx3] RGB triple central diamond ''' # Basic shape of piper plot offset = 0.05 offsety = offset * np.tan(np.pi / 3) h = 0.5 * np.tan(np.pi / 3) ltriangle_x = np.array([0, 0.5, 1, 0]) ltriangle_y = np.array([0, h, 0, 0]) rtriangle_x = ltriangle_x + 2 * offset + 1 rtriangle_y = ltriangle_y diamond_x = np.array([0.5, 1, 1.5, 1, 0.5]) + offset diamond_y = h * (np.array([1, 2, 1, 0, 1])) + (offset * np.tan(np.pi / 3)) fig = plt.figure() ax = fig.add_subplot(111, aspect='equal', frameon=False, xticks=[], yticks=[]) ax.plot(ltriangle_x, ltriangle_y, '-k') ax.plot(rtriangle_x, rtriangle_y, '-k') ax.plot(diamond_x, diamond_y, '-k') # labels and title sns.set_context("notebook") plt.title(plottitle) plt.text(-offset, -offset, u'$Ca^{2+}$', horizontalalignment='left', verticalalignment='center') plt.text(0.5, h + offset, u'$Mg^{2+}$', horizontalalignment='center', verticalalignment='center') plt.text(1 + offset, -offset, u'$Na^+ + K^+$', horizontalalignment='right', verticalalignment='center') plt.text(1 + offset, -offset, u'$HCO_3^- + CO_3^{2-}$', horizontalalignment='left', verticalalignment='center') plt.text(1.5 + 2 * offset, h + offset, u'$SO_4^{2-}$', horizontalalignment='center', verticalalignment='center') plt.text(2 + 3 * offset, -offset, u'$Cl^-$', horizontalalignment='right', verticalalignment='center') # Convert chemistry into plot coordinates gram_mol = { "Ca": 40.078, "Mg": 24.305, "Na": 22.989768, "K": 39.0983, "HCO3": 61.01714, "CO3": 60.0092, "Cl": 35.4527, "SO4": 96.0636 } valence_abs = { "Ca": 2.0, "Mg": 2.0, "Na": 1.0, "K": 1.0, "HCO3": 1.0, "CO3": 2.0, "Cl": 1.0, "SO4": 2.0 } #gmol = np.array( [40.078, 24.305, 22.989768, 39.0983, 61.01714, 60.0092, 35.4527, 96.0636] ) #eqmol = np.array( [2., 2., 1., 1., 1., 2., 1., 2. ]) #n = dat_piper.shape[0] #gram_mol={"Ca":40.078,"Mg":24.305,"Na":22.989768, "K":39.0983,"HCO3":61.01714,"CO3":60.0092,"Cl":35.4527,"SO4":96.0636} #valence_abs= {"Ca":2.0, "Mg":2.0, "Na":1.0, "K":1.0, "HCO3":1.0, "CO3":2.0, "Cl":1.0, "SO4":2.0} df_dat = df[["Ca", "Mg", "Na", "K", "HCO3", "CO3", "Cl", "SO4"]] df_meqL = pd.DataFrame() #initialize an empty dataframe for i in gram_mol: df_meqL[i] = (df_dat[i] / gram_mol[i]) * valence_abs[i] df_meqL = df_meqL[[ "Ca", "Mg", "Na", "K", "HCO3", "CO3", "Cl", "SO4" ]] #reordering(check if this is necessary and or effective) sumcat_pd = df_meqL["Ca"] + df_meqL["Mg"] + df_meqL["Na"] + df_meqL[ "K"] #sum cations suman_pd = df_meqL["HCO3"] + df_meqL["CO3"] + df_meqL["Cl"] + df_meqL[ "SO4"] #sum anions '''meqL = ( dat_piper / gmol ) * eqmol sumcat_pd = np.sum( meqL[:,0:4],axis=1) suman_pd = np.sum( meqL[:,4:8],axis=1) cat = np.zeros( (n,3) ) an = np.zeros( (n,3) )''' cat = pd.DataFrame() #initialize an empty dataframe an = pd.DataFrame() #initialize an empty dataframe cat["Ca"] = df_meqL["Ca"] / sumcat_pd # Ca as proportion cat["Mg"] = df_meqL["Mg"] / sumcat_pd # Mg as proportion cat["Na + K"] = (df_meqL["Na"] + df_meqL["K"]) / sumcat_pd # Na+K as proportion an["HCO3 + CO3"] = (df_meqL["HCO3"] + df_meqL["CO3"]) / suman_pd # HCO3 + CO3 as proportion an["Cl"] = df_meqL["Cl"] / suman_pd # Cl as proportion an["SO4"] = df_meqL["SO4"] / suman_pd # SO4 as proportion # Convert into cartesian coordinates cat_x = 0.5 * (2 * cat["Na + K"] + cat["Mg"]) cat_y = h * cat["Mg"] an_x = 1 + 2 * offset + 0.5 * (2 * an["Cl"] + an["SO4"]) an_y = h * an["SO4"] d_x = an_y / (4 * h) + 0.5 * an_x - cat_y / (4 * h) + 0.5 * cat_x d_y = 0.5 * an_y + h * an_x + 0.5 * cat_y - h * cat_x #df_cart = pd.DataFrame() #carts_list = carts_list{} #carts_list= carts_list.append ("cat_x","cat_y","an_x", "an_y", "d_x", "d_x", "d_y") df['cat_x'] = cat_x df['cat_y'] = cat_y df['an_x'] = an_x df['an_y'] = an_y df['d_x'] = d_x df['d_y'] = d_y print(df.head()) # plot data if color is False: sns.set() sns.scatterplot('cat_x', 'cat_y', data=df, hue='Location', edgecolor='none', legend=None) #, hue='Location') sns.scatterplot('an_x', 'an_y', data=df, hue='Location', edgecolor='none', legend=None) #, hue='Location', legend=False) sns.scatterplot('d_x', 'd_y', data=df, edgecolor='none', hue='Location') #, hue='Location', legend=False) else: sns.set() sns.scatterplot('cat_x', 'cat_y', data=df, color=".2", edgecolor='k') #, hue='Location') sns.scatterplot('an_x', 'an_y', data=df, color=".2", edgecolor='k') #, hue='Location', legend=False) sns.scatterplot('d_x', 'd_y', data=df, color=".2", edgecolor='k') #, hue='Location', legend=False) #plt.plot( cat_x, cat_y, '.k', alpha=alphalevel ) #plt.plot( an_x, an_y, '.k', alpha=alphalevel ) #plt.plot( d_x, d_y, '.k', alpha=alphalevel ) # color coding Piper plot if color == False: # add density color bar if alphalevel < 1 if alphalevel < 1.0: ax1 = fig.add_axes([0.75, 0.4, 0.01, 0.2]) cmap = plt.cm.gray_r #cmap = df['Location'] norm = mpl.colors.Normalize(vmin=0, vmax=1 / alphalevel) cb1 = mpl.colorbar.ColorbarBase(ax1, cmap=cmap, norm=norm, orientation='vertical') cb1.set_label('Dot Density') return (dict(cat=cat, an=an)) #print dict(cat=cat, an=an) else: import scipy.interpolate as interpolate # create empty grids to interpolate to x0 = 0.5 y0 = x0 * np.tan(np.pi / 6) X = np.reshape(np.repeat(np.linspace(0, 2 + 2 * offset, 1000), 1000), (1000, 1000), 'F') Y = np.reshape(np.repeat(np.linspace(0, 2 * h + offsety, 1000), 1000), (1000, 1000), 'C') H = np.nan * np.zeros_like(X) S = np.nan * np.zeros_like(X) V = np.nan * np.ones_like(X) A = np.nan * np.ones_like(X) # create masks for cation, anion triangle and upper and lower diamond ind_cat = np.logical_or(np.logical_and(X < 0.5, Y < 2 * h * X), np.logical_and(X > 0.5, Y < (2 * h * (1 - X)))) ind_an = np.logical_or( np.logical_and(X < 1.5 + (2 * offset), Y < 2 * h * (X - 1 - 2 * offset)), np.logical_and(X > 1.5 + (2 * offset), Y < (2 * h * (1 - (X - 1 - 2 * offset))))) ind_ld = np.logical_and( np.logical_or( np.logical_and(X < 1.0 + offset, Y > -2 * h * X + 2 * h * (1 + 2 * offset)), np.logical_and(X > 1.0 + offset, Y > 2 * h * X - 2 * h)), Y < h + offsety) ind_ud = np.logical_and( np.logical_or( np.logical_and(X < 1.0 + offset, Y < 2 * h * X), np.logical_and(X > 1.0 + offset, Y < -2 * h * X + 4 * h * (1 + offset))), Y > h + offsety) ind_d = np.logical_or(ind_ld == 1, ind_ud == 1) # Hue: convert x,y to polar coordinates # (angle between 0,0 to x0,y0 and x,y to x0,y0) H[ind_cat] = np.pi + np.arctan2(Y[ind_cat] - y0, X[ind_cat] - x0) H[ind_cat] = np.mod(H[ind_cat] - np.pi / 6, 2 * np.pi) H[ind_an] = np.pi + np.arctan2(Y[ind_an] - y0, X[ind_an] - (x0 + 1 + (2 * offset))) H[ind_an] = np.mod(H[ind_an] - np.pi / 6, 2 * np.pi) H[ind_d] = np.pi + np.arctan2(Y[ind_d] - (h + offsety), X[ind_d] - (1 + offset)) # Saturation: 1 at edge of triangle, 0 in the centre, # Clough Tocher interpolation, square root to reduce central white region xy_cat = np.array([[0.0, 0.0], [x0, h], [1.0, 0.0], [x0, y0]]) xy_an = np.array([[1 + (2 * offset), 0.0], [x0 + 1 + (2 * offset), h], [2 + (2 * offset), 0.0], [x0 + 1 + (2 * offset), y0]]) xy_d = np.array([[x0 + offset, h + offsety], [1 + offset, 2 * h + offsety], [x0 + 1 + offset, h + offsety], [1 + offset, offsety], [1 + offset, h + offsety]]) z_cat = np.array([1.0, 1.0, 1.0, 0.0]) z_an = np.array([1.0, 1.0, 1.0, 0.0]) z_d = np.array([1.0, 1.0, 1.0, 1.0, 0.0]) s_cat = interpolate.CloughTocher2DInterpolator(xy_cat, z_cat) s_an = interpolate.CloughTocher2DInterpolator(xy_an, z_an) s_d = interpolate.CloughTocher2DInterpolator(xy_d, z_d) S[ind_cat] = s_cat.__call__(X[ind_cat], Y[ind_cat]) S[ind_an] = s_an.__call__(X[ind_an], Y[ind_an]) S[ind_d] = s_d.__call__(X[ind_d], Y[ind_d]) # Value: 1 everywhere V[ind_cat] = 1.0 V[ind_an] = 1.0 V[ind_d] = 1.0 # Alpha: 1 everywhere A[ind_cat] = 1.0 A[ind_an] = 1.0 A[ind_d] = 1.0 # convert HSV to RGB R, G, B = hsvtorgb(H, S**0.5, V) RGBA = np.dstack((R, G, B, A)) # visualise sns.set() sns.set_context("talk") plt.imshow(RGBA, origin='lower', aspect=1.0, extent=(0, 2 + 2 * offset, 0, 2 * h + offsety)) # calculate RGB triples for data points # hue hcat = np.pi + np.arctan2(cat_y - y0, cat_x - x0) hcat = np.mod(hcat - np.pi / 6, 2 * np.pi) han = np.pi + np.arctan2(an_y - y0, an_x - (x0 + 1 + (2 * offset))) han = np.mod(han - np.pi / 6, 2 * np.pi) hd = np.pi + np.arctan2(d_y - (h + offsety), d_x - (1 + offset)) # saturation scat = s_cat.__call__(cat_x, cat_y)**0.5 san = s_an.__call__(an_x, an_y)**0.5 sd = s_d.__call__(d_x, d_y)**0.5 # value v = np.ones_like(hd) # rgb cat = np.vstack((hsvtorgb(hcat, scat, v))).T an = np.vstack((hsvtorgb(han, san, v))).T d = np.vstack((hsvtorgb(hd, sd, v))).T return (dict(cat=cat, an=an, diamond=d))
def cExNear(x): """Function to compute the exact solution field.""" return cEx_near(x) constructTime['near'] = time.clock()-t t = time.clock() figNum=4 cNear = contPlt.conPlot(cExNear, figNum=figNum) plt.title('nearest ND interpolation') plt.show() executionTime['near'] = time.clock()-t #%% Clough tocher 2D interpolation: t = time.clock() cEx_clough = interpolate.CloughTocher2DInterpolator(coord, cEx, fill_value=0.0) def cExClough(x): """Function to compute the exact solution field.""" return cEx_clough(x) constructTime['clough'] = time.clock()-t t = time.clock() figNum=5 cClough = contPlt.conPlot(cExClough, figNum=figNum) plt.title('clough tocher 2D interpolation') plt.show() executionTime['clough'] = time.clock()-t #%% Results: print('\n\nExecution times for different interpolation functions in Scipy:')