lon = nc.variables['lon'][:] # read element centroid locations latc = nc.variables['latc'][:] lonc = nc.variables['lonc'][:] # read connectivity array nv = nc.variables['nv'][:].T - 1 time_var = nc.variables['time'] # <codecell> nc.variables['h'].shape # <codecell> # create a triangulation object, specifying the triangle connectivity array tri = Tri.Triangulation(lon,lat, triangles=nv) # <codecell> # plot depth using tricontourf h = nc.variables['h'][:] fig = plt.figure(figsize=(12,12)) ax = fig.add_subplot(111,aspect=1.0/np.cos(latc.mean() * np.pi / 180.0)) plt.tricontourf(tri,-h,levels=range(-300,10,10)) plt.colorbar(); # <codecell> # get velocity nearest to current time start = dt.datetime.utcnow()+ dt.timedelta(hours=0) istart = netCDF4.date2index(start,time_var,select='nearest')
n_radii = 10 min_radius = 0.15 radii = np.linspace(min_radius, 0.95, n_radii) angles = np.linspace(0, 2 * np.pi, n_angles, endpoint=False) angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1) angles[:, 1::2] += np.pi / n_angles x = (radii * np.cos(angles)).flatten() y = (radii * np.sin(angles)).flatten() z = function_z(x, y) # Now create the Triangulation. # (Creating a Triangulation without specifying the triangles results in the # Delaunay triangulation of the points.) triang = tri.Triangulation(x, y) # Mask off unwanted triangles. triang.set_mask( np.hypot(x[triang.triangles].mean(axis=1), y[triang.triangles].mean( axis=1)) < min_radius) # ---------------------------------------------------------------------------- # Refine data # ---------------------------------------------------------------------------- refiner = tri.UniformTriRefiner(triang) tri_refi, z_test_refi = refiner.refine_field(z, subdiv=3) # ---------------------------------------------------------------------------- # Plot the triangulation and the high-res iso-contours # ----------------------------------------------------------------------------
# geom = transpose([cos(linspace(0,2*pi,33)), sin(linspace(0,2*pi,33))]) # geom[-1] = geom[0] nE = 5000 dt = 0.005 nsteps = 0 Mach = 0.3 Re = 10000 diameter = 3 if not os.path.exists('fig'): os.mkdir('fig') if not os.path.exists('data'): os.mkdir('data') v, t, b = initMesh(geom, nE, diameter) solver = NavierStokes(v, t, b, Mach, Re) # solver = Euler(v, t, b, Mach, HiRes) solver.integrate(1E-8, solver.freeStream()) solution = zeros([nsteps, solver.nt, 4]) metric = zeros([v.shape[0], 2, 2]) # metric for next adaptation T = Tri.Triangulation(v[:, 0], v[:, 1], t) W = solver.soln tripcolor(v[:, 0], v[:, 1], triangles=t, facecolors=W[:, 0]) for istep, T in enumerate(arange(1, nsteps + 1) * dt): print 'istep: {0}'.format(istep) solver.integrate(T) solution[istep] = solver.soln.copy() metric += solver.metric()
#============ # Make a mesh in the space of parameterisation variables u and v u = np.linspace(0, 2.0 * np.pi, endpoint=True, num=50) v = np.linspace(-0.5, 0.5, endpoint=True, num=10) u, v = np.meshgrid(u, v) u, v = u.flatten(), v.flatten() # This is the Mobius mapping, taking a u, v pair and returning an x, y, z # triple x = (1 + 0.5 * v * np.cos(u / 2.0)) * np.cos(u) y = (1 + 0.5 * v * np.cos(u / 2.0)) * np.sin(u) z = 0.5 * v * np.sin(u / 2.0) # Triangulate parameter space to determine the triangles tri = mtri.Triangulation(u, v) # Plot the surface. The triangles in parameter space determine which x, y, z # points are connected by an edge. ax = fig.add_subplot(1, 2, 1, projection='3d') ax.plot_trisurf(x, y, z, triangles=tri.triangles, cmap=plt.cm.Spectral) ax.set_zlim(-2, 2) #============ # Second plot #============ # Make parameter spaces radii and angles. #n_angles = 36 #n_radii = 8 #min_radius = 0.25
def _griddata(x, y, v, xi, yi, extrap=True, tri=False, mask=False, **kargs): ''' Use griddata instead ''' mpl_tri = kargs.get('mpl_tri', True) tri_type = kargs.get('tri_type', 'cubic') # cubic or linear tri_kind = kargs.get('tri_kind', 'geom') # min_E or geom (for type cubic only) # warning, if x.shape=n,1 x[~mask] will also have 2 dims!! Thus better just use ravel... if x.shape != x.size or y.shape != y.size or v.shape != v.size: x = x.ravel() y = y.ravel() v = v.ravel() if not mask is False: mask = mask.ravel() if mask is False: if np.ma.isMA(v) and np.ma.count_masked(v) > 0: mask = v.mask else: mask = np.zeros(v.shape, 'bool') if not mpl_tri: from matplotlib import delaunay # deprecated in version 1.4 if 0: if not tri: tri = delaunay.Triangulation(x[~mask], y[~mask]) if extrap: u = tri.nn_extrapolator(v[~mask])(xi, yi) else: u = tri.nn_interpolator(v[~mask])(xi, yi) else: # deal with repeated pairs (problem for nn_extrapolator) xy = x[~mask] + 1j * y[~mask] xy, ii = np.unique(xy, 1) if not tri: tri = delaunay.Triangulation(x[~mask][ii], y[~mask][ii]) if extrap: u = tri.nn_extrapolator(v[~mask][ii].data)(xi, yi) else: u = tri.nn_interpolator(v[~mask][ii])(xi, yi) else: import matplotlib.tri as mtri if extrap: # add corners: if 0: dx = (xi.max() - xi.min()) / (1. * xi.size) dy = (yi.max() - yi.min()) / (1. * yi.size) else: # higher distance from domain: dx = (xi.max() - xi.min()) dy = (yi.max() - yi.min()) xv = np.asarray( [xi.min() - dx, xi.max() + dy, xi.max() + dx, xi.min() - dx]) yv = np.asarray( [yi.min() - dy, yi.min() - dy, yi.max() + dy, yi.max() + dy]) vv = np.zeros(4, v.dtype) mv = np.zeros(4, 'bool') for i in range(4): d = (x[~mask] - xv[i])**2 + (y[~mask] - yv[i])**2 j = np.where(d == d.min())[0][0] vv[i] = v[~mask][j] x = np.ma.hstack((x, xv)) y = np.ma.hstack((y, yv)) v = np.ma.hstack((v, vv)) mask = np.hstack((mask, mv)) if not tri: tri = mtri.Triangulation(x[~mask], y[~mask]) if tri_type == 'cubic': u = mtri.CubicTriInterpolator(tri, v[~mask], kind=tri_kind)(xi, yi) elif tri_type == 'linear': u = mtri.LinearTriInterpolator(tri, v[~mask])(xi, yi) return u, tri
def test_delaunay_duplicate_points(): # Issue 838. import warnings # Index 2 is the same as index 0. x = [0, 1, 0, 1, 0] y = [0, 0, 0, 1, 1] duplicate_index = 2 npoints = 4 # Number of non-duplicate points. nduplicates = 1 ntriangles = 2 nedges = 5 # With duplicate points, mpl calls delaunay triangulation but # modified returned arrays. warnings.simplefilter("ignore") # Ignore DuplicatePointWarning. mpl_triang = mtri.Triangulation(x, y) del_triang = mdel.Triangulation(x, y) warnings.resetwarnings() # Points - floating point. assert_equal(len(mpl_triang.x), npoints + nduplicates) assert_equal(len(del_triang.x), npoints) assert_array_almost_equal(mpl_triang.x, x) assert_array_almost_equal(del_triang.x[:duplicate_index], x[:duplicate_index]) assert_array_almost_equal(del_triang.x[duplicate_index:], x[duplicate_index + 1:]) assert_equal(len(mpl_triang.y), npoints + nduplicates) assert_equal(len(del_triang.y), npoints) assert_array_almost_equal(mpl_triang.y, y) assert_array_almost_equal(del_triang.y[:duplicate_index], y[:duplicate_index]) assert_array_almost_equal(del_triang.y[duplicate_index:], y[duplicate_index + 1:]) # Triangles - integers. assert_equal(len(mpl_triang.triangles), ntriangles) assert_equal(np.min(mpl_triang.triangles), 0) assert_equal(np.max(mpl_triang.triangles), npoints - 1 + nduplicates) assert_equal(len(del_triang.triangle_nodes), ntriangles) assert_equal(np.min(del_triang.triangle_nodes), 0) assert_equal(np.max(del_triang.triangle_nodes), npoints - 1) # Convert mpl triangle point indices to delaunay's. converted_indices = np.where(mpl_triang.triangles > duplicate_index, mpl_triang.triangles - nduplicates, mpl_triang.triangles) assert_array_equal(del_triang.triangle_nodes, converted_indices) # Edges - integers. assert_equal(len(mpl_triang.edges), nedges) assert_equal(np.min(mpl_triang.edges), 0) assert_equal(np.max(mpl_triang.edges), npoints - 1 + nduplicates) assert_equal(len(del_triang.edge_db), nedges) assert_equal(np.min(del_triang.edge_db), 0) assert_equal(np.max(del_triang.edge_db), npoints - 1) # Convert mpl edge point indices to delaunay's. converted_indices = np.where(mpl_triang.edges > duplicate_index, mpl_triang.edges - nduplicates, mpl_triang.edges) assert_array_equal(del_triang.edge_db, converted_indices)
def test_tri_smooth_gradient(): # Image comparison based on example trigradient_demo. def dipole_potential(x, y): """ An electric dipole potential V """ r_sq = x**2 + y**2 theta = np.arctan2(y, x) z = np.cos(theta) / r_sq return (np.max(z) - z) / (np.max(z) - np.min(z)) # Creating a Triangulation n_angles = 30 n_radii = 10 min_radius = 0.2 radii = np.linspace(min_radius, 0.95, n_radii) angles = np.linspace(0, 2 * np.pi, n_angles, endpoint=False) angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1) angles[:, 1::2] += np.pi / n_angles x = (radii * np.cos(angles)).flatten() y = (radii * np.sin(angles)).flatten() V = dipole_potential(x, y) triang = mtri.Triangulation(x, y) xmid = x[triang.triangles].mean(axis=1) ymid = y[triang.triangles].mean(axis=1) mask = np.where(xmid * xmid + ymid * ymid < min_radius * min_radius, 1, 0) triang.set_mask(mask) # Refine data - interpolates the electrical potential V refiner = mtri.UniformTriRefiner(triang) tri_refi, z_test_refi = refiner.refine_field(V, subdiv=3) # Computes the electrical field (Ex, Ey) as gradient of -V tci = mtri.CubicTriInterpolator(triang, -V) (Ex, Ey) = tci.gradient(triang.x, triang.y) E_norm = np.sqrt(Ex**2 + Ey**2) # Plot the triangulation, the potential iso-contours and the vector field plt.figure() plt.gca().set_aspect('equal') plt.triplot(triang, color='0.8') levels = np.arange(0., 1., 0.01) cmap = cm.get_cmap(name='hot', lut=None) plt.tricontour(tri_refi, z_test_refi, levels=levels, cmap=cmap, linewidths=[2.0, 1.0, 1.0, 1.0]) # Plots direction of the electrical vector field plt.quiver(triang.x, triang.y, Ex / E_norm, Ey / E_norm, units='xy', scale=10., zorder=3, color='blue', width=0.007, headwidth=3., headlength=4.) plt.show()
def plot_ternary(distribute_func, n_levels=200, subdiv=8, **kwargs): corners = np.array([[0, 0], [1, 0], [0.5, 0.75**0.5]]) # cos(30) triangle = tri.Triangulation(corners[:, 0], corners[:, 1]) # Mid-points of triangle sides opposite of each corner RI = np.linalg.inv(np.vstack((corners.T, [1, 1, 1]))) def xy2bc(xys, tol=1.e-3): ''' Converts 2D Cartesian coordinates to barycentric. according to https://en.wikipedia.org/wiki/Barycentric_coordinate_system#Conversion_between_barycentric_and_Cartesian_coordinates''' xysT = np.transpose(xys) ones = [1] * len(xys) xysT1 = np.vstack((xysT, ones)) lambda_ = RI.dot(xysT1).T return np.clip(lambda_, a_min=tol, a_max=1.0 - tol) def tick_labels(scale=100, size=20): return [ str(int(i)) for i in np.arange(0, scale / size * (size + 1), scale / size) ] def tick_txy(location, width=1.0, size=20): height = width * 0.75**0.5 if location == 'left': xy = np.array(( np.arange(0, width / 2 / size * (size + 1), width / 2 / size), np.arange(0, height / size * (size + 1), height / size), )) return xy[0, :][::-1], xy[1, :][::-1] if location == 'right': xy = np.array(( np.arange(0.5, 0.5 + width / 2 / size * (size + 1), width / 2 / size), np.arange(0, height / size * (size + 1), height / size), )) return xy[0, :][::-1], xy[1, :] if location == 'bottom': xy = np.array(( np.arange(0, width / size * (size + 1), width / size), np.array((0.0, ) * (size + 1)), )) return xy[0, :], xy[1, :] refiner = tri.UniformTriRefiner(triangle) trimesh = refiner.refine_triangulation(subdiv=subdiv) bc = xy2bc(list(zip(trimesh.x, trimesh.y))) pvals = distribute_func(bc) fig = plt.figure() ax = fig.add_subplot(111, aspect='equal') ax.triplot(triangle, color='black') trimap = ax.tricontourf(trimesh, pvals, n_levels, **kwargs) # trimap = ax.tricontourf(x,y,t,n_levels,**kwargs) offset = 0.02 linewidth = 1. for x, y, s in zip(*tick_txy('left'), tick_labels()): ax.text(x - offset / 2, y + 0.75**0.5 * offset, s, verticalalignment='center', horizontalalignment='right') ax.plot((x, x - offset / 2), (y, y + 0.75**0.5 * offset), '-', lw=linewidth, color='black') for x, y, s in zip(*tick_txy('right'), tick_labels()): ax.text(x + offset / 2, y, s, verticalalignment='center', horizontalalignment='left') ax.plot((x, x + offset / 2), (y, y), '-', lw=linewidth, color='black') for x, y, s in zip(*tick_txy('bottom'), tick_labels()): ax.text(x - offset / 2, y - 0.75**0.5 * offset, s, verticalalignment='top', horizontalalignment='center') ax.plot((x, x - offset / 2), (y, y - 0.75**0.5 * offset), '-', lw=linewidth, color='black') ''' from mpl_toolkits.axes_grid1 import make_axes_locatable divider = make_axes_locatable(plt.gca()) cax = divider.append_axes("right", "5%", pad="-8%") fig.colorbar(trimap, cax=cax) ''' fig.colorbar(trimap) ax.set_aspect('equal') fig.tight_layout(pad=0) ax.axis('equal') # ax.set_xlim(0, 1) # ax.set_ylim(-0.02, 0.75**0.5+0.02) ax.axis('off') return fig
cylHull = cc.genHull(xCyl, yCyl, zCyl) # Convert to theta-phi space # Add slightly periodic boundaries for nicer contouring rad, theta, phi = cc.toSpherical(xCyl, yCyl, zCyl) boundaryWidth = 0.2 thetaMin = np.amin(theta) thetaMax = np.amax(theta) phiMin = np.amin(phi) phiMax = np.amax(phi) theta, phi, A = cc.semiPeriodicBounds(theta, phi, A, boundaryWidth) # Triangulate mesh = tri.Triangulation(theta, phi) # mesh = cc.maskBounds(theta, [0,np.pi], phi, [-np.pi,np.pi], mesh) # Draw contour lines fig, ax = plt.subplots() contours = ax.tricontour(mesh, A, levels=20) ax.set_xlabel(r'$\theta$') ax.set_ylabel(r'$\phi$') ax.set_xlim(thetaMin, thetaMax) ax.set_ylim(phiMin, phiMax) # Project contours onto cylinder and generate current loops # currentLoops = [loop0, loop1, loop2, ...] # loop0 = [[x0,y0,z0], [x1,y1,z1], ...] # Since we had semi-periodic boundaries, drop points outside old bounds currentLoops = cc.genLoops(contours, cylHull, [thetaMin, thetaMax],
for i in hull1.vertices: xn1.append(verts1[i][0]) yn1.append(verts1[i][1]) zn1.append(verts1[i][2]) for i in hull2.vertices: xn2.append(verts2[i][0]) yn2.append(verts2[i][1]) zn2.append(verts2[i][2]) verts1 = np.transpose(verts1) verts2 = np.transpose(verts2) #ax.scatter(xn1, yn1, zn1); #ax.scatter(xn2, yn2, zn2); tri1 = tri.Triangulation(verts1[0], verts1[1], triangles=hull1.simplices) tri2 = tri.Triangulation(verts2[0], verts2[1], triangles=hull2.simplices) ax.plot_trisurf(tri1, verts1[2], color="grey", alpha=0.5, linewidth=0, antialiased=True) ax.plot_trisurf(tri2, verts2[2], color="grey", linewidth=0,
lats = nc.variables['lat'][:] latc = nc.variables['latc'][:] lonc = nc.variables['lonc'][:] time = nc.variables['time'][:] h = nc.variables['h'][:] start = datetime.datetime.now(pytz.timezone("America/New_York")) T = [] for i in range(len(time)): t = datetime.datetime(1858, 11, 17) + datetime.timedelta( days=int(time[i])) + datetime.timedelta( seconds=int(time[i] % 1 * 24 * 3600)) t = gmt_to_loc(t) T.append(t) itime = np.argmin(abs(np.array(T) - start)) #find nearest time daystr = T[itime] tri = Tri.Triangulation(lons, lats) ilayer = 0 #0 is surface,-1 is bottom u = nc.variables['u'][itime, ilayer, :] v = nc.variables['v'][itime, ilayer, :] CX = [ alon - 7 * one_minute, alon + 7 * one_minute, alat - 7 * one_minute, alat + 7 * one_minute ] # box you want to plot subsample = 2 ind = argwhere((lonc >= CX[0]) & (lonc <= CX[1]) & (latc >= CX[2]) & (latc <= CX[3])) # find velocity points in bounding box np.random.shuffle(ind) Nvec = int(len(ind) / subsample) idv = ind[:Nvec] indx = argwhere((lons >= CX[0]) & (lons <= CX[1]) & (lats >= CX[2]) & (lats <= CX[3])) # find points in bounding box
def list_plot3d_tuples(v, interpolation_type, **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) 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, color='yellow', interpolation_type='linear', num_points=5) # indirect doctest Graphics3d Object :: sage: list_plot3d(m, color='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)], color='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 not (-0.9 <= 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( "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.get('num_points', int(4 * numpy.sqrt(len(x)))) # arbitrary choice - assuming more or less a n x n 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])), **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])), **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.get('smoothing', 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) def f(x, y): return interpolate.bisplev(x, y, s) return plot3d(f, (xmin, xmax), (ymin, ymax), plot_points=[num_points, num_points], **kwds)
def draw(self, renderer): xs3d, ys3d, zs3d = self._verts3d xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M) self.set_positions((xs[0], ys[0]), (xs[1], ys[1])) FancyArrowPatch.draw(self, renderer) x = [1, 0, 0] y = [0, 1, 0] z = [0, 0, 1] pts = np.vstack([x, y]).T tess = scipy.spatial.Delaunay(pts) tri = tess.vertices triang = mtri.Triangulation(x=pts[:, 0], y=pts[:, 1], triangles=tri) fig = plt.figure() ax = fig.gca(projection='3d') ax.plot_trisurf(triang, z, alpha=.3, color='red', edgecolors='blue') ax.set_axis_off() for i in range(3): EndPs = [[0, 0], [0, 0], [0, 0]] EndPs[i][1] = 1.4 art = Arrow3D(EndPs[0], EndPs[1], EndPs[2], mutation_scale=20, lw=3, arrowstyle="-|>",
'''Functions for drawing contours of Dirichlet distributions.''' # Author: Thomas Boggs import numpy as np import matplotlib.pyplot as plt import matplotlib.tri as tri _corners = np.array([[0, 0], [1, 0], [0.5, 0.75**0.5]]) _triangle = tri.Triangulation(_corners[:, 0], _corners[:, 1]) _midpoints = [(_corners[(i + 1) % 3] + _corners[(i + 2) % 3]) / 2.0 \ for i in range(3)] def xy2bc(xy, tol=1.e-3): '''Converts 2D Cartesian coordinates to barycentric. Arguments: `xy`: A length-2 sequence containing the x and y value. ''' s = [(_corners[i] - _midpoints[i]).dot(xy - _midpoints[i]) / 0.75 \ for i in range(3)] return np.clip(s, tol, 1.0 - tol) class Dirichlet(object): def __init__(self, alpha): '''Creates Dirichlet distribution with parameter `alpha`.''' from math import gamma from operator import mul
def test_triinterp(): # Test points within triangles of masked triangulation. x, y = np.meshgrid(np.arange(4), np.arange(4)) x = x.ravel() y = y.ravel() z = 1.23 * x - 4.79 * y triangles = [[0, 1, 4], [1, 5, 4], [1, 2, 5], [2, 6, 5], [2, 3, 6], [3, 7, 6], [4, 5, 8], [5, 9, 8], [5, 6, 9], [6, 10, 9], [6, 7, 10], [7, 11, 10], [8, 9, 12], [9, 13, 12], [9, 10, 13], [10, 14, 13], [10, 11, 14], [11, 15, 14]] mask = np.zeros(len(triangles)) mask[8:10] = 1 triang = mtri.Triangulation(x, y, triangles, mask) linear_interp = mtri.LinearTriInterpolator(triang, z) cubic_min_E = mtri.CubicTriInterpolator(triang, z) cubic_geom = mtri.CubicTriInterpolator(triang, z, kind='geom') xs = np.linspace(0.25, 2.75, 6) ys = [0.25, 0.75, 2.25, 2.75] xs, ys = np.meshgrid(xs, ys) # Testing arrays with array.ndim = 2 for interp in (linear_interp, cubic_min_E, cubic_geom): zs = interp(xs, ys) assert_array_almost_equal(zs, (1.23 * xs - 4.79 * ys)) # Test points outside triangulation. xs = [-0.25, 1.25, 1.75, 3.25] ys = xs xs, ys = np.meshgrid(xs, ys) for interp in (linear_interp, cubic_min_E, cubic_geom): zs = linear_interp(xs, ys) assert_array_equal(zs.mask, [[True] * 4] * 4) # Test mixed configuration (outside / inside). xs = np.linspace(0.25, 1.75, 6) ys = [0.25, 0.75, 1.25, 1.75] xs, ys = np.meshgrid(xs, ys) for interp in (linear_interp, cubic_min_E, cubic_geom): zs = interp(xs, ys) assert_array_almost_equal(zs, (1.23 * xs - 4.79 * ys)) mask = (xs >= 1) * (xs <= 2) * (ys >= 1) * (ys <= 2) assert_array_equal(zs.mask, mask) # 2nd order patch test: on a grid with an 'arbitrary shaped' triangle, # patch test shall be exact for quadratic functions and cubic # interpolator if *kind* = user (a, b, c) = (1.23, -4.79, 0.6) def quad(x, y): return a * (x - 0.5)**2 + b * (y - 0.5)**2 + c * x * y def gradient_quad(x, y): return (2 * a * (x - 0.5) + c * y, 2 * b * (y - 0.5) + c * x) x = np.array([0.2, 0.33367, 0.669, 0., 1., 1., 0.]) y = np.array([0.3, 0.80755, 0.4335, 0., 0., 1., 1.]) triangles = np.array([[0, 1, 2], [3, 0, 4], [4, 0, 2], [4, 2, 5], [1, 5, 2], [6, 5, 1], [6, 1, 0], [6, 0, 3]]) triang = mtri.Triangulation(x, y, triangles) z = quad(x, y) dz = gradient_quad(x, y) # test points for 2nd order patch test xs = np.linspace(0., 1., 5) ys = np.linspace(0., 1., 5) xs, ys = np.meshgrid(xs, ys) cubic_user = mtri.CubicTriInterpolator(triang, z, kind='user', dz=dz) interp_zs = cubic_user(xs, ys) assert_array_almost_equal(interp_zs, quad(xs, ys)) (interp_dzsdx, interp_dzsdy) = cubic_user.gradient(x, y) (dzsdx, dzsdy) = gradient_quad(x, y) assert_array_almost_equal(interp_dzsdx, dzsdx) assert_array_almost_equal(interp_dzsdy, dzsdy) # Cubic improvement: cubic interpolation shall perform better than linear # on a sufficiently dense mesh for a quadratic function. n = 11 x, y = np.meshgrid(np.linspace(0., 1., n + 1), np.linspace(0., 1., n + 1)) x = x.ravel() y = y.ravel() z = quad(x, y) triang = mtri.Triangulation(x, y, triangles=meshgrid_triangles(n + 1)) xs, ys = np.meshgrid(np.linspace(0.1, 0.9, 5), np.linspace(0.1, 0.9, 5)) xs = xs.ravel() ys = ys.ravel() linear_interp = mtri.LinearTriInterpolator(triang, z) cubic_min_E = mtri.CubicTriInterpolator(triang, z) cubic_geom = mtri.CubicTriInterpolator(triang, z, kind='geom') zs = quad(xs, ys) diff_lin = np.abs(linear_interp(xs, ys) - zs) for interp in (cubic_min_E, cubic_geom): diff_cubic = np.abs(interp(xs, ys) - zs) assert (np.max(diff_lin) >= 10. * np.max(diff_cubic)) assert (np.dot(diff_lin, diff_lin) >= 100. * np.dot(diff_cubic, diff_cubic))
def test_delaunay_insufficient_points(x, y): with pytest.raises(ValueError): mtri.Triangulation(x, y)
def test_triinterpcubic_C1_continuity(): # Below the 4 tests which demonstrate C1 continuity of the # TriCubicInterpolator (testing the cubic shape functions on arbitrary # triangle): # # 1) Testing continuity of function & derivatives at corner for all 9 # shape functions. Testing also function values at same location. # 2) Testing C1 continuity along each edge (as gradient is polynomial of # 2nd order, it is sufficient to test at the middle). # 3) Testing C1 continuity at triangle barycenter (where the 3 subtriangles # meet) # 4) Testing C1 continuity at median 1/3 points (midside between 2 # subtriangles) # Utility test function check_continuity def check_continuity(interpolator, loc, values=None): """ Checks the continuity of interpolator (and its derivatives) near location loc. Can check the value at loc itself if *values* is provided. *interpolator* TriInterpolator *loc* location to test (x0, y0) *values* (optional) array [z0, dzx0, dzy0] to check the value at *loc* """ n_star = 24 # Number of continuity points in a boundary of loc epsilon = 1.e-10 # Distance for loc boundary k = 100. # Continuity coefficient (loc_x, loc_y) = loc star_x = loc_x + epsilon * np.cos(np.linspace(0., 2 * np.pi, n_star)) star_y = loc_y + epsilon * np.sin(np.linspace(0., 2 * np.pi, n_star)) z = interpolator([loc_x], [loc_y])[0] (dzx, dzy) = interpolator.gradient([loc_x], [loc_y]) if values is not None: assert_array_almost_equal(z, values[0]) assert_array_almost_equal(dzx[0], values[1]) assert_array_almost_equal(dzy[0], values[2]) diff_z = interpolator(star_x, star_y) - z (tab_dzx, tab_dzy) = interpolator.gradient(star_x, star_y) diff_dzx = tab_dzx - dzx diff_dzy = tab_dzy - dzy assert_array_less(diff_z, epsilon * k) assert_array_less(diff_dzx, epsilon * k) assert_array_less(diff_dzy, epsilon * k) # Drawing arbitrary triangle (a, b, c) inside a unit square. (ax, ay) = (0.2, 0.3) (bx, by) = (0.33367, 0.80755) (cx, cy) = (0.669, 0.4335) x = np.array([ax, bx, cx, 0., 1., 1., 0.]) y = np.array([ay, by, cy, 0., 0., 1., 1.]) triangles = np.array([[0, 1, 2], [3, 0, 4], [4, 0, 2], [4, 2, 5], [1, 5, 2], [6, 5, 1], [6, 1, 0], [6, 0, 3]]) triang = mtri.Triangulation(x, y, triangles) for idof in range(9): z = np.zeros(7, dtype=np.float64) dzx = np.zeros(7, dtype=np.float64) dzy = np.zeros(7, dtype=np.float64) values = np.zeros([3, 3], dtype=np.float64) case = idof // 3 values[case, idof % 3] = 1.0 if case == 0: z[idof] = 1.0 elif case == 1: dzx[idof % 3] = 1.0 elif case == 2: dzy[idof % 3] = 1.0 interp = mtri.CubicTriInterpolator(triang, z, kind='user', dz=(dzx, dzy)) # Test 1) Checking values and continuity at nodes check_continuity(interp, (ax, ay), values[:, 0]) check_continuity(interp, (bx, by), values[:, 1]) check_continuity(interp, (cx, cy), values[:, 2]) # Test 2) Checking continuity at midside nodes check_continuity(interp, ((ax + bx) * 0.5, (ay + by) * 0.5)) check_continuity(interp, ((ax + cx) * 0.5, (ay + cy) * 0.5)) check_continuity(interp, ((cx + bx) * 0.5, (cy + by) * 0.5)) # Test 3) Checking continuity at barycenter check_continuity(interp, ((ax + bx + cx) / 3., (ay + by + cy) / 3.)) # Test 4) Checking continuity at median 1/3-point check_continuity(interp, ((4. * ax + bx + cx) / 6., (4. * ay + by + cy) / 6.)) check_continuity(interp, ((ax + 4. * bx + cx) / 6., (ay + 4. * by + cy) / 6.)) check_continuity(interp, ((ax + bx + 4. * cx) / 6., (ay + by + 4. * cy) / 6.))
def test_triinterp_colinear(): # Tests interpolating inside a triangulation with horizontal colinear # points (refer also to the tests :func:`test_trifinder` ). # # These are not valid triangulations, but we try to deal with the # simplest violations (i. e. those handled by default TriFinder). # # Note that the LinearTriInterpolator and the CubicTriInterpolator with # kind='min_E' or 'geom' still pass a linear patch test. # We also test interpolation inside a flat triangle, by forcing # *tri_index* in a call to :meth:`_interpolate_multikeys`. # If +ve, triangulation is OK, if -ve triangulation invalid, # if zero have colinear points but should pass tests anyway. delta = 0. x0 = np.array([1.5, 0, 1, 2, 3, 1.5, 1.5]) y0 = np.array([-1, 0, 0, 0, 0, delta, 1]) # We test different affine transformations of the initial figure; to # avoid issues related to round-off errors we only use integer # coefficients (otherwise the Triangulation might become invalid even with # delta == 0). transformations = [[1, 0], [0, 1], [1, 1], [1, 2], [-2, -1], [-2, 1]] for transformation in transformations: x_rot = transformation[0] * x0 + transformation[1] * y0 y_rot = -transformation[1] * x0 + transformation[0] * y0 (x, y) = (x_rot, y_rot) z = 1.23 * x - 4.79 * y triangles = [[0, 2, 1], [0, 3, 2], [0, 4, 3], [1, 2, 5], [2, 3, 5], [3, 4, 5], [1, 5, 6], [4, 6, 5]] triang = mtri.Triangulation(x, y, triangles) xs = np.linspace(np.min(triang.x), np.max(triang.x), 20) ys = np.linspace(np.min(triang.y), np.max(triang.y), 20) xs, ys = np.meshgrid(xs, ys) xs = xs.ravel() ys = ys.ravel() mask_out = (triang.get_trifinder()(xs, ys) == -1) zs_target = np.ma.array(1.23 * xs - 4.79 * ys, mask=mask_out) linear_interp = mtri.LinearTriInterpolator(triang, z) cubic_min_E = mtri.CubicTriInterpolator(triang, z) cubic_geom = mtri.CubicTriInterpolator(triang, z, kind='geom') for interp in (linear_interp, cubic_min_E, cubic_geom): zs = interp(xs, ys) assert_array_almost_equal(zs_target, zs) # Testing interpolation inside the flat triangle number 4: [2, 3, 5] # by imposing *tri_index* in a call to :meth:`_interpolate_multikeys` itri = 4 pt1 = triang.triangles[itri, 0] pt2 = triang.triangles[itri, 1] xs = np.linspace(triang.x[pt1], triang.x[pt2], 10) ys = np.linspace(triang.y[pt1], triang.y[pt2], 10) zs_target = 1.23 * xs - 4.79 * ys for interp in (linear_interp, cubic_min_E, cubic_geom): zs, = interp._interpolate_multikeys(xs, ys, tri_index=itri * np.ones(10, dtype=np.int32)) assert_array_almost_equal(zs_target, zs)
def test_triinterp_transformations(): # 1) Testing that the interpolation scheme is invariant by rotation of the # whole figure. # Note: This test is non-trivial for a CubicTriInterpolator with # kind='min_E'. It does fail for a non-isotropic stiffness matrix E of # :class:`_ReducedHCT_Element` (tested with E=np.diag([1., 1., 1.])), and # provides a good test for :meth:`get_Kff_and_Ff`of the same class. # # 2) Also testing that the interpolation scheme is invariant by expansion # of the whole figure along one axis. n_angles = 20 n_radii = 10 min_radius = 0.15 def z(x, y): r1 = np.sqrt((0.5 - x)**2 + (0.5 - y)**2) theta1 = np.arctan2(0.5 - x, 0.5 - y) r2 = np.sqrt((-x - 0.2)**2 + (-y - 0.2)**2) theta2 = np.arctan2(-x - 0.2, -y - 0.2) z = -(2 * (np.exp( (r1 / 10)**2) - 1) * 30. * np.cos(7. * theta1) + (np.exp( (r2 / 10)**2) - 1) * 30. * np.cos(11. * theta2) + 0.7 * (x**2 + y**2)) return (np.max(z) - z) / (np.max(z) - np.min(z)) # First create the x and y coordinates of the points. radii = np.linspace(min_radius, 0.95, n_radii) angles = np.linspace(0 + n_angles, 2 * np.pi + n_angles, n_angles, endpoint=False) angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1) angles[:, 1::2] += np.pi / n_angles x0 = (radii * np.cos(angles)).flatten() y0 = (radii * np.sin(angles)).flatten() triang0 = mtri.Triangulation(x0, y0) # Delaunay triangulation z0 = z(x0, y0) # Then create the test points xs0 = np.linspace(-1., 1., 23) ys0 = np.linspace(-1., 1., 23) xs0, ys0 = np.meshgrid(xs0, ys0) xs0 = xs0.ravel() ys0 = ys0.ravel() interp_z0 = {} for i_angle in range(2): # Rotating everything theta = 2 * np.pi / n_angles * i_angle x = np.cos(theta) * x0 + np.sin(theta) * y0 y = -np.sin(theta) * x0 + np.cos(theta) * y0 xs = np.cos(theta) * xs0 + np.sin(theta) * ys0 ys = -np.sin(theta) * xs0 + np.cos(theta) * ys0 triang = mtri.Triangulation(x, y, triang0.triangles) linear_interp = mtri.LinearTriInterpolator(triang, z0) cubic_min_E = mtri.CubicTriInterpolator(triang, z0) cubic_geom = mtri.CubicTriInterpolator(triang, z0, kind='geom') dic_interp = { 'lin': linear_interp, 'min_E': cubic_min_E, 'geom': cubic_geom } # Testing that the interpolation is invariant by rotation... for interp_key in ['lin', 'min_E', 'geom']: interp = dic_interp[interp_key] if i_angle == 0: interp_z0[interp_key] = interp(xs0, ys0) # storage else: interpz = interp(xs, ys) assert_array_almost_equal(interpz, interp_z0[interp_key]) scale_factor = 987654.3210 for scaled_axis in ('x', 'y'): # Scaling everything (expansion along scaled_axis) if scaled_axis == 'x': x = scale_factor * x0 y = y0 xs = scale_factor * xs0 ys = ys0 else: x = x0 y = scale_factor * y0 xs = xs0 ys = scale_factor * ys0 triang = mtri.Triangulation(x, y, triang0.triangles) linear_interp = mtri.LinearTriInterpolator(triang, z0) cubic_min_E = mtri.CubicTriInterpolator(triang, z0) cubic_geom = mtri.CubicTriInterpolator(triang, z0, kind='geom') dic_interp = { 'lin': linear_interp, 'min_E': cubic_min_E, 'geom': cubic_geom } # Testing that the interpolation is invariant by expansion along # 1 axis... for interp_key in ['lin', 'min_E', 'geom']: interpz = dic_interp[interp_key](xs, ys) assert_array_almost_equal(interpz, interp_z0[interp_key])
print(t2 - t1) # Run the image. m.run_image(name="image", nphot=1e5, npix=25, pixelsize=1.0, lam="1000", \ phi=0, incl=0, code="radmc3d", dpc=100, verbose=False, \ unstructured=True, camera_nrrefine=8, camera_refine_criterion=1, \ nostar=True) print(m.images["image"].image.shape) npix_trift = int(m.images["image"].image[:, 0].size**0.5) # Plot the image. triang = tri.Triangulation(m.images["image"].x, m.images["image"].y) plt.tripcolor(triang, m.images["image"].image[:, 0], "ko-") plt.triplot(triang, "k.-", linewidth=0.1, markersize=0.1) plt.axes().set_aspect("equal") plt.xlim(-12, 12) plt.ylim(-12, 12) plt.xlabel('$\Delta$ R.A. ["]', fontsize=14) plt.ylabel('$\Delta$ Dec. ["]', fontsize=14) plt.gca().tick_params(labelsize=14) plt.show()
def centrifugal_asym(rhop, Rlfs, omega, Zeff, A_imp, Z_imp, Te, Ti, main_ion_A=2, plot=False, nz=None, geqdsk=None): """Estimate impurity poloidal asymmetry effects from centrifugal forces. The result of this function is :math:`\lambda`, defined such that .. math:: n(r,\theta) = n_0(r) \times \exp\left{\lambda(\rho) (R(r,\theta)^2- R_0^2)\right} See Odstrcil et al. 2018 Plasma Phys. Control. Fusion 60 014003 for details on centrifugal asymmetries. Also see Appendix A of Angioni et al 2014 Nucl. Fusion 54 083028 for details on these should also be accounted for when comparing transport coefficients used in Aurora (on a rvol grid) to coefficients used in codes that use other coordinate systems (e.g. based on rmid). Args: rhop : array (nr,) Sqrt of normalized poloidal flux grid. Rlfs : array (nr,) Major radius on the Low Field Side (LFS), at points corresponding to rhop values omega : array (nt,nr) or (nr,) [ rad/s ] Toroidal rotation on Aurora temporal time_grid and radial rhop_grid (or, equivalently, rvol_grid) grids. Zeff : array (nt,nr), (nr,) or float Effective plasma charge on Aurora temporal time_grid and radial rhop_grid (or, equivalently, rvol_grid) grids. Alternatively, users may give Zeff as a float (taken constant over time and space). A_imp : float Impurity ion atomic mass number (e.g. 40 for Ca) Z_imp : array (nr, ) or int Charge state of the impurity of interest. This can be an array, giving the expected charge state at every radial position, or just a float. Te : array (nr,nt) Electron temperature (eV) Ti : array (nr, nt) Background ion temperature (eV) main_ion_A : int, optional Background ion atomic mass number. Default is 2 for D. Keyword Args: plot : bool If True, plot asymmetry factor :math:`\lambda` vs. radius and show the predicted 2D impurity density distribution at the last time point. nz : array (nr,nZ) Impurity charge state densities (output of Aurora at a specific time slice), only used for 2D plotting. geqdsk : dict Dictionary containing the `omfit_eqdsk` reading of the EFIT g-file. Returns: CF_lam : array (nr,) Asymmetry factor, defined as :math:`\lambda` in the expression above. """ if omega.ndim == 1: omega = omega[None, :] # take constant in time if isinstance(Zeff, (int, float)): Zeff = np.array(Zeff) * np.ones_like(Ti) if Zeff.ndim == 1: Zeff = Zeff[None, :] # take constant in time # deuterium mach number mach = np.sqrt(2. * m_p / q_electron * (omega * Rlfs[None, :])**2 / (2. * Ti)) # valid for deuterium plasma with Zeff almost constants on flux surfaces CF_lam = A_imp / 2. * (mach / Rlfs[None, :])**2 * ( 1. - Z_imp * main_ion_A / A_imp * Zeff * Te / (Ti + Zeff * Te)) # centrifugal asymmetry is only relevant on closed flux surfaces CF_lam[:, rhop > 1.] = 0 if plot: # show centrifugal asymmetry lambda as a function of radius fig, ax = plt.subplots() ax.plot(rhop, CF_lam.T) ax.set_xlabel(r'$\rho_p$') ax.set_ylabel(r'$\lambda$') # plot expected radial impurity density over the poloidal cross section fig, ax = plt.subplots() if isinstance(Z_imp, (int, float)): # select charge state of interest nz_sel = nz[:, int(Z_imp) - 1] else: # use total impurity density if Z_imp was given as a vector nz_sel = nz.sum(1) rhop_surfs = np.sqrt(geqdsk['fluxSurfaces']['geo']['psin']) Rs = [] Zs = [] vals = [] for ii, surf in enumerate(geqdsk['fluxSurfaces']['flux']): # FSA nz on this flux surface at the last time point nz_sel_i = interp1d(rhop, nz_sel)(rhop_surfs[ii]) CF_lam_i = interp1d(rhop, CF_lam[-1, :])(rhop_surfs[ii]) Rs = np.concatenate((Rs, geqdsk['fluxSurfaces']['flux'][ii]['R'])) Zs = np.concatenate((Zs, geqdsk['fluxSurfaces']['flux'][ii]['Z'])) vals = np.concatenate( (vals, nz_sel_i * np.exp(CF_lam_i * (geqdsk['fluxSurfaces']['flux'][ii]['R']**2 - geqdsk['RMAXIS']**2)))) triang = tri.Triangulation(Rs, Zs) cntr1 = ax.tricontourf(triang, vals, levels=300) ax.plot(geqdsk['RBBBS'], geqdsk['ZBBBS'], c='k') ax.scatter(geqdsk['RMAXIS'], geqdsk['ZMAXIS'], marker='x', c='k') ax.axis('equal') ax.set_xlabel('R [m]') ax.set_ylabel('Z [m]') plt.tight_layout() return CF_lam
if use_RBCs: print("Applying Radiating Boundary Conditions...") K, b = apply_RBCs(K, b, P, T, C, n_bdry, n_corn, eps_p) elif use_RBCs is None: print("Leaving boundaries as homogenous neumann conditions...") else: print("Applying Dirichlet (V=0) at Domain Boundary") V_bdry = np.zeros(np.size(n_bdry)) K, b = apply_dirichlet_conditions(K, b, n_bdry, n_cent, V_bdry) print("Solving the Matrix Equation...") K = K.tocsr() V = linalg.spsolve(K, b) print("Plotting the potential distribution...") triang_out = triangle_mod.Triangulation(P[:, 0], P[:, 1], triangles=T) fig1, ax1 = plt.subplots(dpi=400) ax1.set_aspect('equal') tpc = ax1.tripcolor(triang_out, V, cmap="turbo", shading='gouraud') fig1.colorbar(tpc) ax1.set_title('Potential distribution') plt.show() # Calculate the electric field E = -FE_gradient(V, P, T) #/2#/1.5 # Calculate the capacitance by integrating the normal electric field around the small rod Q = 0 L = 0 for e in range(N_e):
def _mesh2triang(mesh): xy = mesh.coordinates() return tri.Triangulation(xy[:, 0], xy[:, 1], mesh.cells())
# read the lines file lines_data = np.loadtxt(lines_file, delimiter=',', skiprows=0, unpack=True) shapeid = lines_data[0, :] #shapeid = shapeid.astype(np.int32) x = lines_data[1, :] y = lines_data[2, :] # create the new output variables z = np.zeros(len(x)) sta = np.zeros(len(x)) tempid = np.zeros(len(x)) dist = np.zeros(len(x)) # create tin triangulation object using matplotlib tin = mtri.Triangulation(t_x, t_y, t_ikle) # perform the triangulation interpolator = mtri.LinearTriInterpolator(tin, t_z) z = interpolator(x, y) # if the node is outside of the boundary of the domain, assign value -999.0 # as the interpolated node where_are_NaNs = np.isnan(z) z[where_are_NaNs] = -999.0 if (np.sum(where_are_NaNs) > 0): print('#####################################################') print('') print('WARNING: Some nodes are outside of the TIN boundary!!!') print('')
def mask_extrap(x, y, v, inplace=False, norm_xy=False, mpl_tri=True): ''' Extrapolate numpy array at masked points. Based on delaunay triangulation provided by matplotlib. ''' #if np.ma.isMA(v) and v.size!=v.count(): mask=v.mask if np.ma.is_masked(v): mask = v.mask else: return v sh = v.shape x = x.ravel() y = y.ravel() v = v.ravel() mask = mask.ravel() if inplace: u = v else: u = v.copy() if norm_xy: rxy = (x.max() - x.min()) / (y.max() - y.min()) y = y * rxy if not mpl_tri: from matplotlib import delaunay # deprecated in version 1.4 # nn_extrapolator may have problems dealing with regular grids, # nans may be obtained. One simple solution is to rotate the domain! x, y = rot2d(x, y, np.pi / 3.) if 0: tri = delaunay.Triangulation(x[~mask], y[~mask]) u[mask] = tri.nn_extrapolator(u[~mask])(x[mask], y[mask]) else: # deal with repeated pairs (problem for nn_extrapolator) xy = x[~mask] + 1j * y[~mask] xy, ii = np.unique(xy, 1) tri = delaunay.Triangulation(x[~mask][ii], y[~mask][ii]) u[mask] = tri.nn_extrapolator(u[~mask][ii])(x[mask], y[mask]) if np.any(np.isnan(u)): mask = np.isnan(u) tri = delaunay.Triangulation(x[~mask], y[~mask]) u[mask] = tri.nn_extrapolator(u[~mask])(x[mask], y[mask]) else: import matplotlib.tri as mtri # add corners: xv = np.asarray([x.min() - 1, x.max() + 1, x.max() + 1, x.min() - 1]) yv = np.asarray([y.min() - 1, y.min() - 1, y.max() + 1, y.max() + 1]) vv = np.zeros(4, v.dtype) mv = np.zeros(4, 'bool') for i in range(4): d = (x[~mask] - xv[i])**2 + (y[~mask] - yv[i])**2 j = np.where(d == d.min())[0][0] vv[i] = u[~mask][j] #x=np.ma.hstack((x.flat,xv)) # use ravel at top instead! x = np.ma.hstack((x, xv)) y = np.ma.hstack((y, yv)) u = np.ma.hstack((u, vv)) mask = np.hstack((mask, mv)) tri = mtri.Triangulation(x[~mask], y[~mask]) #print u.shape,x.shape,y.shape,mask.shape u[mask] = mtri.CubicTriInterpolator(tri, u[~mask])(x[mask], y[mask]) if np.any(np.isnan(u)): mask = np.isnan(u) tri = mtri.Triangulation(x[~mask], y[~mask]) u[mask] = mtri.CubicTriInterpolator(tri, u[~mask])(x[mask], y[mask]) u = u[:-4] u.shape = sh if not inplace: if not np.ma.is_masked(u): u = u.data return u
daystr = tm.strftime('%Y-%b-%d %H:%M') print(daystr) # In[12]: # round to nearest 10 minutes to make titles look better tm += dt.timedelta(minutes=5) tm -= dt.timedelta(minutes=tm.minute % 10, seconds=tm.second, microseconds=tm.microsecond) daystr = tm.strftime('%Y-%b-%d %H:%M') print(daystr) # In[13]: tri = Tri.Triangulation(lon, lat, triangles=nv) # In[14]: # get current at layer [0 = surface, -1 = bottom] ilayer = 0 u = ncv['u'][itime, ilayer, :] v = ncv['v'][itime, ilayer, :] # In[15]: #boston harbor levels = np.arange(-34, 2, 1) # depth contours to plot ax = [-70.97, -70.82, 42.25, 42.35] # maxvel = 0.5 subsample = 3
def plot1(): """plot1""" data = np.random.rand(100, 2) triangles = tri.Triangulation(data[:, 0], data[:, 1]) plt.triplot(triangles) plt.show()
def test_trifinder(): # Test points within triangles of masked triangulation. x, y = np.meshgrid(np.arange(4), np.arange(4)) x = x.ravel() y = y.ravel() triangles = [[0, 1, 4], [1, 5, 4], [1, 2, 5], [2, 6, 5], [2, 3, 6], [3, 7, 6], [4, 5, 8], [5, 9, 8], [5, 6, 9], [6, 10, 9], [6, 7, 10], [7, 11, 10], [8, 9, 12], [9, 13, 12], [9, 10, 13], [10, 14, 13], [10, 11, 14], [11, 15, 14]] mask = np.zeros(len(triangles)) mask[8:10] = 1 triang = mtri.Triangulation(x, y, triangles, mask) trifinder = triang.get_trifinder() xs = [0.25, 1.25, 2.25, 3.25] ys = [0.25, 1.25, 2.25, 3.25] xs, ys = np.meshgrid(xs, ys) xs = xs.ravel() ys = ys.ravel() tris = trifinder(xs, ys) assert_array_equal( tris, [0, 2, 4, -1, 6, -1, 10, -1, 12, 14, 16, -1, -1, -1, -1, -1]) tris = trifinder(xs - 0.5, ys - 0.5) assert_array_equal( tris, [-1, -1, -1, -1, -1, 1, 3, 5, -1, 7, -1, 11, -1, 13, 15, 17]) # Test points exactly on boundary edges of masked triangulation. xs = [0.5, 1.5, 2.5, 0.5, 1.5, 2.5, 1.5, 1.5, 0.0, 1.0, 2.0, 3.0] ys = [0.0, 0.0, 0.0, 3.0, 3.0, 3.0, 1.0, 2.0, 1.5, 1.5, 1.5, 1.5] tris = trifinder(xs, ys) assert_array_equal(tris, [0, 2, 4, 13, 15, 17, 3, 14, 6, 7, 10, 11]) # Test points exactly on boundary corners of masked triangulation. xs = [0.0, 3.0] ys = [0.0, 3.0] tris = trifinder(xs, ys) assert_array_equal(tris, [0, 17]) # Test triangles with horizontal colinear points. These are not valid # triangulations, but we try to deal with the simplest violations. delta = 0.0 # If +ve, triangulation is OK, if -ve triangulation invalid, # if zero have colinear points but should pass tests anyway. x = [1.5, 0, 1, 2, 3, 1.5, 1.5] y = [-1, 0, 0, 0, 0, delta, 1] triangles = [[0, 2, 1], [0, 3, 2], [0, 4, 3], [1, 2, 5], [2, 3, 5], [3, 4, 5], [1, 5, 6], [4, 6, 5]] triang = mtri.Triangulation(x, y, triangles) trifinder = triang.get_trifinder() xs = [-0.1, 0.4, 0.9, 1.4, 1.9, 2.4, 2.9] ys = [-0.1, 0.1] xs, ys = np.meshgrid(xs, ys) tris = trifinder(xs, ys) assert_array_equal(tris, [[-1, 0, 0, 1, 1, 2, -1], [-1, 6, 6, 6, 7, 7, -1]]) # Test triangles with vertical colinear points. These are not valid # triangulations, but we try to deal with the simplest violations. delta = 0.0 # If +ve, triangulation is OK, if -ve triangulation invalid, # if zero have colinear points but should pass tests anyway. x = [-1, -delta, 0, 0, 0, 0, 1] y = [1.5, 1.5, 0, 1, 2, 3, 1.5] triangles = [[0, 1, 2], [0, 1, 5], [1, 2, 3], [1, 3, 4], [1, 4, 5], [2, 6, 3], [3, 6, 4], [4, 6, 5]] triang = mtri.Triangulation(x, y, triangles) trifinder = triang.get_trifinder() xs = [-0.1, 0.1] ys = [-0.1, 0.4, 0.9, 1.4, 1.9, 2.4, 2.9] xs, ys = np.meshgrid(xs, ys) tris = trifinder(xs, ys) assert_array_equal( tris, [[-1, -1], [0, 5], [0, 5], [0, 6], [1, 6], [1, 7], [-1, -1]]) # Test that changing triangulation by setting a mask causes the trifinder # to be reinitialised. x = [0, 1, 0, 1] y = [0, 0, 1, 1] triangles = [[0, 1, 2], [1, 3, 2]] triang = mtri.Triangulation(x, y, triangles) trifinder = triang.get_trifinder() xs = [-0.2, 0.2, 0.8, 1.2] ys = [0.5, 0.5, 0.5, 0.5] tris = trifinder(xs, ys) assert_array_equal(tris, [-1, 0, 1, -1]) triang.set_mask([1, 0]) assert_equal(trifinder, triang.get_trifinder()) tris = trifinder(xs, ys) assert_array_equal(tris, [-1, -1, 1, -1])
def _contours(self, par=None, expr=None, distr=None, velocity=None, values=None, slice=1, global_cos=True, species=None, style='isolines', ignore_inactive=True, **kwargs): """ Business functions for plotting library. :param global_cos: If True, use global coordinate system (default: local) :return: GeoDataFrame """ import numpy as np import matplotlib.pyplot as plt import matplotlib.tri as tri # check if keywords arguments are corrent - dirty fix, this required reimplementation. if slice > self.doc.getNumberOfSlices(): raise ValueError("no entitiy provided (either of par, distr or expr parameter must be called) or slice number out of range.") # set current species if species is not None: if type(species) == str: speciesID = self.doc.findSpecies(species) elif type(species) == int: speciesID = species else: raise ValueError("species must be string (for name) or integer (for id)") self.doc.setMultiSpeciesId(speciesID) # read incidence matrix and node coordinates imat = self.doc.c.mesh.get_imatrix2d(slice=slice, ignore_inactive=ignore_inactive, split_quads_to_triangles=True) x, y = self.doc.getParamValues(Enum.P_MSH_X), self.doc.getParamValues(Enum.P_MSH_Y) if global_cos: X0 = self.doc.getOriginX() Y0 = self.doc.getOriginY() x = [X + X0 for X in x] y = [Y + Y0 for Y in y] # create Triangulation object femesh = tri.Triangulation(x, y, np.asarray(imat)) if style == "edges": return plt.triplot(femesh, **kwargs) elif style == "faces": from matplotlib.colors import LinearSegmentedColormap allgrey_cm = LinearSegmentedColormap.from_list("all_grey", np.array([[0.5, 0.5, 0.5, 1.], [0.5, 0.5, 0.5, 1.]])) return plt.tripcolor(femesh, np.zeros_like(range(self.doc.getNumberOfNodes())), cmap=allgrey_cm, **kwargs) # get values, remove nan values (=inactive elements) if par is not None: self.doc.getParamSize(par) # workaround for a crashbug in FEFLOW values = self.doc.getParamValues(par) elif expr is not None: if type(expr) == str: exprID = self.doc.getNodalExprDistrIdByName(expr) elif type(expr) == int: exprID = expr else: raise ValueError("expr must be string (for name) or integer (for id)") values = [self.doc.getNodalExprDistrValue(exprID, n) for n in range(self.doc.getNumberOfNodes())] elif distr is not None: if type(distr) == str: distrID = self.doc.getNodalRefDistrIdByName(distr) elif type(distr) == int: distrID = distr else: raise ValueError("distr must be string (for name) or integer (for id)") values = [self.doc.getNodalRefDistrValue(distrID, n) for n in range(self.doc.getNumberOfNodes())] elif velocity is not None: if velocity not in ['v_x', 'v_y', 'v_z','v_norm']: raise ValueError("Allowed options vor parameter 'velocity': 'v_x', 'v_y', 'v_z' or 'v_norm'") values = self.doc.c.mesh.df.nodes(velocity=True)[velocity] elif values is not None: values = values # OK, so this is just to make clear that we are using the values directly! else: raise ValueError("either of parameter par, expr or distr must be provided!") # set nan values to zero values = np.nan_to_num(np.asarray(values)) # generate polygons from matplotlib (suppress output) if style == "continuous": return plt.tripcolor(femesh, values, shading='gouraud', **kwargs) elif style == "patches": try: return plt.tripcolor(femesh, facecolors=values.flatten(), **kwargs) except ValueError as e: # problems with quad elements --> need to have values for split elements, was # not a poblem for nodal values... if "Length of color" in str(e): raise NotImplementedError("This function does not support quad elements yet") else: raise e elif style == "fringes": contourset = plt.tricontourf(femesh, values, **kwargs) return contourset elif style == "isolines": contourset = plt.tricontour(femesh, values, **kwargs) return contourset else: raise ValueError("unkonwn style " + str(style))
def contour_array(self, a, masked_values=None, **kwargs): """ Contour an array. If the array is three-dimensional, then the method will contour the layer tied to this class (self.layer). Parameters ---------- a : numpy.ndarray Array to plot. masked_values : iterable of floats, ints Values to mask. **kwargs : dictionary keyword arguments passed to matplotlib.pyplot.pcolormesh Returns ------- contour_set : matplotlib.pyplot.contour """ try: import matplotlib.tri as tri except ImportError: err_msg = "Matplotlib must be updated to use contour_array" raise ImportError(err_msg) if not isinstance(a, np.ndarray): a = np.array(a) xcentergrid = np.array(self.mg.xcellcenters) ycentergrid = np.array(self.mg.ycellcenters) if self.mg.grid_type == "structured": if a.ndim == 3: plotarray = a[self.layer, :, :] elif a.ndim == 2: plotarray = a elif a.ndim == 1: plotarray = a else: raise Exception('Array must be of dimension 1, 2 or 3') elif self.mg.grid_type == "vertex": if a.ndim == 2: plotarray = a[self.layer, :] elif a.ndim == 1: plotarray = a else: raise Exception('Array must be of dimension 1, 2 or 3') else: plotarray = a if masked_values is not None: for mval in masked_values: plotarray = np.ma.masked_equal(plotarray, mval) if 'ax' in kwargs: ax = kwargs.pop('ax') else: ax = self.ax if 'colors' in kwargs.keys(): if 'cmap' in kwargs.keys(): kwargs.pop('cmap') plot_triplot = False if 'plot_triplot' in kwargs: plot_triplot = kwargs.pop('plot_triplot') if 'extent' in kwargs: extent = kwargs.pop('extent') if self.mg.grid_type in ('structured', 'vertex'): idx = (xcentergrid >= extent[0]) & ( xcentergrid <= extent[1]) & (ycentergrid >= extent[2]) & ( ycentergrid <= extent[3]) plotarray = plotarray[idx] xcentergrid = xcentergrid[idx] ycentergrid = ycentergrid[idx] plotarray = plotarray.flatten() xcentergrid = xcentergrid.flatten() ycentergrid = ycentergrid.flatten() triang = tri.Triangulation(xcentergrid, ycentergrid) mask = None try: amask = plotarray.mask mask = [False for i in range(triang.triangles.shape[0])] for ipos, (n0, n1, n2) in enumerate(triang.triangles): if amask[n0] or amask[n1] or amask[n2]: mask[ipos] = True triang.set_mask(mask) except (AttributeError, IndexError): pass contour_set = ax.tricontour(triang, plotarray, **kwargs) if plot_triplot: ax.triplot(triang, color='black', marker='o', lw=0.75) ax.set_xlim(self.extent[0], self.extent[1]) ax.set_ylim(self.extent[2], self.extent[3]) return contour_set