Example #1
0
    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.)
Example #2
0
    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)
Example #3
0
    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))
Example #4
0
    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
Example #5
0
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
Example #6
0
 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
Example #7
0
 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)
Example #8
0
    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)
Example #9
0
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
Example #10
0
    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
Example #11
0
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(),) )
Example #12
0
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
Example #14
0
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
Example #15
0
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))
Example #16
0
 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)
Example #17
0
    def __call__(self, Zin):

        F = interpolate.CloughTocher2DInterpolator(self.XY, Zin)

        return F(self.XYout)
Example #18
0
    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)
Example #19
0
    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:
Example #20
0
    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)
Example #21
0
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))
Example #22
0
    #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))
Example #23
0
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))
Example #24
0
# 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)
Example #25
0
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)
Example #26
0
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)
Example #27
0
 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)
Example #28
0
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))
Example #29
0
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:')