1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165 |
- import numpy as np
- from numpy.testing import (
- assert_array_equal, assert_array_almost_equal, assert_array_less)
- import numpy.ma.testutils as matest
- import pytest
- import matplotlib as mpl
- import matplotlib.cm as cm
- import matplotlib.pyplot as plt
- import matplotlib.tri as mtri
- from matplotlib.path import Path
- from matplotlib.testing.decorators import image_comparison
- def test_delaunay():
- # No duplicate points, regular grid.
- nx = 5
- ny = 4
- x, y = np.meshgrid(np.linspace(0.0, 1.0, nx), np.linspace(0.0, 1.0, ny))
- x = x.ravel()
- y = y.ravel()
- npoints = nx*ny
- ntriangles = 2 * (nx-1) * (ny-1)
- nedges = 3*nx*ny - 2*nx - 2*ny + 1
- # Create delaunay triangulation.
- triang = mtri.Triangulation(x, y)
- # The tests in the remainder of this function should be passed by any
- # triangulation that does not contain duplicate points.
- # Points - floating point.
- assert_array_almost_equal(triang.x, x)
- assert_array_almost_equal(triang.y, y)
- # Triangles - integers.
- assert len(triang.triangles) == ntriangles
- assert np.min(triang.triangles) == 0
- assert np.max(triang.triangles) == npoints-1
- # Edges - integers.
- assert len(triang.edges) == nedges
- assert np.min(triang.edges) == 0
- assert np.max(triang.edges) == npoints-1
- # Neighbors - integers.
- # Check that neighbors calculated by C++ triangulation class are the same
- # as those returned from delaunay routine.
- neighbors = triang.neighbors
- triang._neighbors = None
- assert_array_equal(triang.neighbors, neighbors)
- # Is each point used in at least one triangle?
- assert_array_equal(np.unique(triang.triangles), np.arange(npoints))
- def test_delaunay_duplicate_points():
- npoints = 10
- duplicate = 7
- duplicate_of = 3
- np.random.seed(23)
- x = np.random.random(npoints)
- y = np.random.random(npoints)
- x[duplicate] = x[duplicate_of]
- y[duplicate] = y[duplicate_of]
- # Create delaunay triangulation.
- triang = mtri.Triangulation(x, y)
- # Duplicate points should be ignored, so the index of the duplicate points
- # should not appear in any triangle.
- assert_array_equal(np.unique(triang.triangles),
- np.delete(np.arange(npoints), duplicate))
- def test_delaunay_points_in_line():
- # Cannot triangulate points that are all in a straight line, but check
- # that delaunay code fails gracefully.
- x = np.linspace(0.0, 10.0, 11)
- y = np.linspace(0.0, 10.0, 11)
- with pytest.raises(RuntimeError):
- mtri.Triangulation(x, y)
- # Add an extra point not on the line and the triangulation is OK.
- x = np.append(x, 2.0)
- y = np.append(y, 8.0)
- mtri.Triangulation(x, y)
- @pytest.mark.parametrize('x, y', [
- # Triangulation should raise a ValueError if passed less than 3 points.
- ([], []),
- ([1], [5]),
- ([1, 2], [5, 6]),
- # Triangulation should also raise a ValueError if passed duplicate points
- # such that there are less than 3 unique points.
- ([1, 2, 1], [5, 6, 5]),
- ([1, 2, 2], [5, 6, 6]),
- ([1, 1, 1, 2, 1, 2], [5, 5, 5, 6, 5, 6]),
- ])
- def test_delaunay_insufficient_points(x, y):
- with pytest.raises(ValueError):
- mtri.Triangulation(x, y)
- def test_delaunay_robust():
- # Fails when mtri.Triangulation uses matplotlib.delaunay, works when using
- # qhull.
- tri_points = np.array([
- [0.8660254037844384, -0.5000000000000004],
- [0.7577722283113836, -0.5000000000000004],
- [0.6495190528383288, -0.5000000000000003],
- [0.5412658773652739, -0.5000000000000003],
- [0.811898816047911, -0.40625000000000044],
- [0.7036456405748561, -0.4062500000000004],
- [0.5953924651018013, -0.40625000000000033]])
- test_points = np.asarray([
- [0.58, -0.46],
- [0.65, -0.46],
- [0.65, -0.42],
- [0.7, -0.48],
- [0.7, -0.44],
- [0.75, -0.44],
- [0.8, -0.48]])
- # Utility function that indicates if a triangle defined by 3 points
- # (xtri, ytri) contains the test point xy. Avoid calling with a point that
- # lies on or very near to an edge of the triangle.
- def tri_contains_point(xtri, ytri, xy):
- tri_points = np.vstack((xtri, ytri)).T
- return Path(tri_points).contains_point(xy)
- # Utility function that returns how many triangles of the specified
- # triangulation contain the test point xy. Avoid calling with a point that
- # lies on or very near to an edge of any triangle in the triangulation.
- def tris_contain_point(triang, xy):
- return sum(tri_contains_point(triang.x[tri], triang.y[tri], xy)
- for tri in triang.triangles)
- # Using matplotlib.delaunay, an invalid triangulation is created with
- # overlapping triangles; qhull is OK.
- triang = mtri.Triangulation(tri_points[:, 0], tri_points[:, 1])
- for test_point in test_points:
- assert tris_contain_point(triang, test_point) == 1
- # If ignore the first point of tri_points, matplotlib.delaunay throws a
- # KeyError when calculating the convex hull; qhull is OK.
- triang = mtri.Triangulation(tri_points[1:, 0], tri_points[1:, 1])
- @image_comparison(['tripcolor1.png'])
- def test_tripcolor():
- x = np.asarray([0, 0.5, 1, 0, 0.5, 1, 0, 0.5, 1, 0.75])
- y = np.asarray([0, 0, 0, 0.5, 0.5, 0.5, 1, 1, 1, 0.75])
- triangles = np.asarray([
- [0, 1, 3], [1, 4, 3],
- [1, 2, 4], [2, 5, 4],
- [3, 4, 6], [4, 7, 6],
- [4, 5, 9], [7, 4, 9], [8, 7, 9], [5, 8, 9]])
- # Triangulation with same number of points and triangles.
- triang = mtri.Triangulation(x, y, triangles)
- Cpoints = x + 0.5*y
- xmid = x[triang.triangles].mean(axis=1)
- ymid = y[triang.triangles].mean(axis=1)
- Cfaces = 0.5*xmid + ymid
- plt.subplot(121)
- plt.tripcolor(triang, Cpoints, edgecolors='k')
- plt.title('point colors')
- plt.subplot(122)
- plt.tripcolor(triang, facecolors=Cfaces, edgecolors='k')
- plt.title('facecolors')
- def test_no_modify():
- # Test that Triangulation does not modify triangles array passed to it.
- triangles = np.array([[3, 2, 0], [3, 1, 0]], dtype=np.int32)
- points = np.array([(0, 0), (0, 1.1), (1, 0), (1, 1)])
- old_triangles = triangles.copy()
- mtri.Triangulation(points[:, 0], points[:, 1], triangles).edges
- assert_array_equal(old_triangles, triangles)
- 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.
- #
- # If +ve, triangulation is OK, if -ve triangulation invalid,
- # if zero have colinear points but should pass tests anyway.
- delta = 0.0
- 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.
- #
- # If +ve, triangulation is OK, if -ve triangulation invalid,
- # if zero have colinear points but should pass tests anyway.
- delta = 0.0
- 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 trifinder == triang.get_trifinder()
- tris = trifinder(xs, ys)
- assert_array_equal(tris, [-1, -1, 1, -1])
- 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)
- matest.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_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_triinterpcubic_cg_solver():
- # Now 3 basic tests of the Sparse CG solver, used for
- # TriCubicInterpolator with *kind* = 'min_E'
- # 1) A commonly used test involves a 2d Poisson matrix.
- def poisson_sparse_matrix(n, m):
- """
- Return the sparse, (n*m, n*m) matrix in coo format resulting from the
- discretisation of the 2-dimensional Poisson equation according to a
- finite difference numerical scheme on a uniform (n, m) grid.
- """
- l = m*n
- rows = np.concatenate([
- np.arange(l, dtype=np.int32),
- np.arange(l-1, dtype=np.int32), np.arange(1, l, dtype=np.int32),
- np.arange(l-n, dtype=np.int32), np.arange(n, l, dtype=np.int32)])
- cols = np.concatenate([
- np.arange(l, dtype=np.int32),
- np.arange(1, l, dtype=np.int32), np.arange(l-1, dtype=np.int32),
- np.arange(n, l, dtype=np.int32), np.arange(l-n, dtype=np.int32)])
- vals = np.concatenate([
- 4*np.ones(l, dtype=np.float64),
- -np.ones(l-1, dtype=np.float64), -np.ones(l-1, dtype=np.float64),
- -np.ones(l-n, dtype=np.float64), -np.ones(l-n, dtype=np.float64)])
- # In fact +1 and -1 diags have some zeros
- vals[l:2*l-1][m-1::m] = 0.
- vals[2*l-1:3*l-2][m-1::m] = 0.
- return vals, rows, cols, (n*m, n*m)
- # Instantiating a sparse Poisson matrix of size 48 x 48:
- (n, m) = (12, 4)
- mat = mtri.triinterpolate._Sparse_Matrix_coo(*poisson_sparse_matrix(n, m))
- mat.compress_csc()
- mat_dense = mat.to_dense()
- # Testing a sparse solve for all 48 basis vector
- for itest in range(n*m):
- b = np.zeros(n*m, dtype=np.float64)
- b[itest] = 1.
- x, _ = mtri.triinterpolate._cg(A=mat, b=b, x0=np.zeros(n*m),
- tol=1.e-10)
- assert_array_almost_equal(np.dot(mat_dense, x), b)
- # 2) Same matrix with inserting 2 rows - cols with null diag terms
- # (but still linked with the rest of the matrix by extra-diag terms)
- (i_zero, j_zero) = (12, 49)
- vals, rows, cols, _ = poisson_sparse_matrix(n, m)
- rows = rows + 1*(rows >= i_zero) + 1*(rows >= j_zero)
- cols = cols + 1*(cols >= i_zero) + 1*(cols >= j_zero)
- # adding extra-diag terms
- rows = np.concatenate([rows, [i_zero, i_zero-1, j_zero, j_zero-1]])
- cols = np.concatenate([cols, [i_zero-1, i_zero, j_zero-1, j_zero]])
- vals = np.concatenate([vals, [1., 1., 1., 1.]])
- mat = mtri.triinterpolate._Sparse_Matrix_coo(vals, rows, cols,
- (n*m + 2, n*m + 2))
- mat.compress_csc()
- mat_dense = mat.to_dense()
- # Testing a sparse solve for all 50 basis vec
- for itest in range(n*m + 2):
- b = np.zeros(n*m + 2, dtype=np.float64)
- b[itest] = 1.
- x, _ = mtri.triinterpolate._cg(A=mat, b=b, x0=np.ones(n*m + 2),
- tol=1.e-10)
- assert_array_almost_equal(np.dot(mat_dense, x), b)
- # 3) Now a simple test that summation of duplicate (i.e. with same rows,
- # same cols) entries occurs when compressed.
- vals = np.ones(17, dtype=np.float64)
- rows = np.array([0, 1, 2, 0, 0, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1],
- dtype=np.int32)
- cols = np.array([0, 1, 2, 1, 1, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2],
- dtype=np.int32)
- dim = (3, 3)
- mat = mtri.triinterpolate._Sparse_Matrix_coo(vals, rows, cols, dim)
- mat.compress_csc()
- mat_dense = mat.to_dense()
- assert_array_almost_equal(mat_dense, np.array([
- [1., 2., 0.], [2., 1., 5.], [0., 5., 1.]], dtype=np.float64))
- def test_triinterpcubic_geom_weights():
- # Tests to check computation of weights for _DOF_estimator_geom:
- # The weight sum per triangle can be 1. (in case all angles < 90 degrees)
- # or (2*w_i) where w_i = 1-alpha_i/np.pi is the weight of apex i; alpha_i
- # is the apex angle > 90 degrees.
- (ax, ay) = (0., 1.687)
- x = np.array([ax, 0.5*ax, 0., 1.])
- y = np.array([ay, -ay, 0., 0.])
- z = np.zeros(4, dtype=np.float64)
- triangles = [[0, 2, 3], [1, 3, 2]]
- sum_w = np.zeros([4, 2]) # 4 possibilities; 2 triangles
- for theta in np.linspace(0., 2*np.pi, 14): # rotating the figure...
- x_rot = np.cos(theta)*x + np.sin(theta)*y
- y_rot = -np.sin(theta)*x + np.cos(theta)*y
- triang = mtri.Triangulation(x_rot, y_rot, triangles)
- cubic_geom = mtri.CubicTriInterpolator(triang, z, kind='geom')
- dof_estimator = mtri.triinterpolate._DOF_estimator_geom(cubic_geom)
- weights = dof_estimator.compute_geom_weights()
- # Testing for the 4 possibilities...
- sum_w[0, :] = np.sum(weights, 1) - 1
- for itri in range(3):
- sum_w[itri+1, :] = np.sum(weights, 1) - 2*weights[:, itri]
- assert_array_almost_equal(np.min(np.abs(sum_w), axis=0),
- np.array([0., 0.], dtype=np.float64))
- 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.hypot(0.5 - x, 0.5 - y)
- theta1 = np.arctan2(0.5 - x, 0.5 - y)
- r2 = np.hypot(-x - 0.2, -y - 0.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)
- matest.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}
- # Test 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)
- matest.assert_array_almost_equal(interpz, interp_z0[interp_key])
- @image_comparison(['tri_smooth_contouring.png'], remove_text=True, tol=0.07)
- def test_tri_smooth_contouring():
- # Image comparison based on example tricontour_smooth_user.
- n_angles = 20
- n_radii = 10
- min_radius = 0.15
- def z(x, y):
- r1 = np.hypot(0.5 - x, 0.5 - y)
- theta1 = np.arctan2(0.5 - x, 0.5 - y)
- r2 = np.hypot(-x - 0.2, -y - 0.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)
- triang0.set_mask(np.hypot(x0[triang0.triangles].mean(axis=1),
- y0[triang0.triangles].mean(axis=1))
- < min_radius)
- # Then the plot
- refiner = mtri.UniformTriRefiner(triang0)
- tri_refi, z_test_refi = refiner.refine_field(z0, subdiv=4)
- levels = np.arange(0., 1., 0.025)
- plt.triplot(triang0, lw=0.5, color='0.5')
- plt.tricontour(tri_refi, z_test_refi, levels=levels, colors="black")
- @image_comparison(['tri_smooth_gradient.png'], remove_text=True, tol=0.092)
- 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)
- triang.set_mask(np.hypot(x[triang.triangles].mean(axis=1),
- y[triang.triangles].mean(axis=1))
- < min_radius)
- # 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.hypot(Ex, Ey)
- # 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.)
- # We are leaving ax.use_sticky_margins as True, so the
- # view limits are the contour data limits.
- def test_tritools():
- # Tests TriAnalyzer.scale_factors on masked triangulation
- # Tests circle_ratios on equilateral and right-angled triangle.
- x = np.array([0., 1., 0.5, 0., 2.])
- y = np.array([0., 0., 0.5*np.sqrt(3.), -1., 1.])
- triangles = np.array([[0, 1, 2], [0, 1, 3], [1, 2, 4]], dtype=np.int32)
- mask = np.array([False, False, True], dtype=bool)
- triang = mtri.Triangulation(x, y, triangles, mask=mask)
- analyser = mtri.TriAnalyzer(triang)
- assert_array_almost_equal(analyser.scale_factors,
- np.array([1., 1./(1.+0.5*np.sqrt(3.))]))
- assert_array_almost_equal(
- analyser.circle_ratios(rescale=False),
- np.ma.masked_array([0.5, 1./(1.+np.sqrt(2.)), np.nan], mask))
- # Tests circle ratio of a flat triangle
- x = np.array([0., 1., 2.])
- y = np.array([1., 1.+3., 1.+6.])
- triangles = np.array([[0, 1, 2]], dtype=np.int32)
- triang = mtri.Triangulation(x, y, triangles)
- analyser = mtri.TriAnalyzer(triang)
- assert_array_almost_equal(analyser.circle_ratios(), np.array([0.]))
- # Tests TriAnalyzer.get_flat_tri_mask
- # Creates a triangulation of [-1, 1] x [-1, 1] with contiguous groups of
- # 'flat' triangles at the 4 corners and at the center. Checks that only
- # those at the borders are eliminated by TriAnalyzer.get_flat_tri_mask
- n = 9
- def power(x, a):
- return np.abs(x)**a*np.sign(x)
- x = np.linspace(-1., 1., n+1)
- x, y = np.meshgrid(power(x, 2.), power(x, 0.25))
- x = x.ravel()
- y = y.ravel()
- triang = mtri.Triangulation(x, y, triangles=meshgrid_triangles(n+1))
- analyser = mtri.TriAnalyzer(triang)
- mask_flat = analyser.get_flat_tri_mask(0.2)
- verif_mask = np.zeros(162, dtype=bool)
- corners_index = [0, 1, 2, 3, 14, 15, 16, 17, 18, 19, 34, 35, 126, 127,
- 142, 143, 144, 145, 146, 147, 158, 159, 160, 161]
- verif_mask[corners_index] = True
- assert_array_equal(mask_flat, verif_mask)
- # Now including a hole (masked triangle) at the center. The center also
- # shall be eliminated by get_flat_tri_mask.
- mask = np.zeros(162, dtype=bool)
- mask[80] = True
- triang.set_mask(mask)
- mask_flat = analyser.get_flat_tri_mask(0.2)
- center_index = [44, 45, 62, 63, 78, 79, 80, 81, 82, 83, 98, 99, 116, 117]
- verif_mask[center_index] = True
- assert_array_equal(mask_flat, verif_mask)
- def test_trirefine():
- # Testing subdiv=2 refinement
- n = 3
- subdiv = 2
- x = np.linspace(-1., 1., n+1)
- x, y = np.meshgrid(x, x)
- x = x.ravel()
- y = y.ravel()
- mask = np.zeros(2*n**2, dtype=bool)
- mask[n**2:] = True
- triang = mtri.Triangulation(x, y, triangles=meshgrid_triangles(n+1),
- mask=mask)
- refiner = mtri.UniformTriRefiner(triang)
- refi_triang = refiner.refine_triangulation(subdiv=subdiv)
- x_refi = refi_triang.x
- y_refi = refi_triang.y
- n_refi = n * subdiv**2
- x_verif = np.linspace(-1., 1., n_refi+1)
- x_verif, y_verif = np.meshgrid(x_verif, x_verif)
- x_verif = x_verif.ravel()
- y_verif = y_verif.ravel()
- ind1d = np.in1d(np.around(x_verif*(2.5+y_verif), 8),
- np.around(x_refi*(2.5+y_refi), 8))
- assert_array_equal(ind1d, True)
- # Testing the mask of the refined triangulation
- refi_mask = refi_triang.mask
- refi_tri_barycenter_x = np.sum(refi_triang.x[refi_triang.triangles],
- axis=1) / 3.
- refi_tri_barycenter_y = np.sum(refi_triang.y[refi_triang.triangles],
- axis=1) / 3.
- tri_finder = triang.get_trifinder()
- refi_tri_indices = tri_finder(refi_tri_barycenter_x,
- refi_tri_barycenter_y)
- refi_tri_mask = triang.mask[refi_tri_indices]
- assert_array_equal(refi_mask, refi_tri_mask)
- # Testing that the numbering of triangles does not change the
- # interpolation result.
- x = np.asarray([0.0, 1.0, 0.0, 1.0])
- y = np.asarray([0.0, 0.0, 1.0, 1.0])
- triang = [mtri.Triangulation(x, y, [[0, 1, 3], [3, 2, 0]]),
- mtri.Triangulation(x, y, [[0, 1, 3], [2, 0, 3]])]
- z = np.hypot(x - 0.3, y - 0.4)
- # Refining the 2 triangulations and reordering the points
- xyz_data = []
- for i in range(2):
- refiner = mtri.UniformTriRefiner(triang[i])
- refined_triang, refined_z = refiner.refine_field(z, subdiv=1)
- xyz = np.dstack((refined_triang.x, refined_triang.y, refined_z))[0]
- xyz = xyz[np.lexsort((xyz[:, 1], xyz[:, 0]))]
- xyz_data += [xyz]
- assert_array_almost_equal(xyz_data[0], xyz_data[1])
- @pytest.mark.parametrize('interpolator',
- [mtri.LinearTriInterpolator,
- mtri.CubicTriInterpolator],
- ids=['linear', 'cubic'])
- def test_trirefine_masked(interpolator):
- # Repeated points means we will have fewer triangles than points, and thus
- # get masking.
- x, y = np.mgrid[:2, :2]
- x = np.repeat(x.flatten(), 2)
- y = np.repeat(y.flatten(), 2)
- z = np.zeros_like(x)
- tri = mtri.Triangulation(x, y)
- refiner = mtri.UniformTriRefiner(tri)
- interp = interpolator(tri, z)
- refiner.refine_field(z, triinterpolator=interp, subdiv=2)
- def meshgrid_triangles(n):
- """
- Return (2*(N-1)**2, 3) array of triangles to mesh (N, N)-point np.meshgrid.
- """
- tri = []
- for i in range(n-1):
- for j in range(n-1):
- a = i + j*n
- b = (i+1) + j*n
- c = i + (j+1)*n
- d = (i+1) + (j+1)*n
- tri += [[a, b, d], [a, d, c]]
- return np.array(tri, dtype=np.int32)
- def test_triplot_return():
- # Check that triplot returns the artists it adds
- ax = plt.figure().add_subplot()
- triang = mtri.Triangulation(
- [0.0, 1.0, 0.0, 1.0], [0.0, 0.0, 1.0, 1.0],
- triangles=[[0, 1, 3], [3, 2, 0]])
- assert ax.triplot(triang, "b-") is not None, \
- 'triplot should return the artist it adds'
- def test_trirefiner_fortran_contiguous_triangles():
- # github issue 4180. Test requires two arrays of triangles that are
- # identical except that one is C-contiguous and one is fortran-contiguous.
- triangles1 = np.array([[2, 0, 3], [2, 1, 0]])
- assert not np.isfortran(triangles1)
- triangles2 = np.array(triangles1, copy=True, order='F')
- assert np.isfortran(triangles2)
- x = np.array([0.39, 0.59, 0.43, 0.32])
- y = np.array([33.99, 34.01, 34.19, 34.18])
- triang1 = mtri.Triangulation(x, y, triangles1)
- triang2 = mtri.Triangulation(x, y, triangles2)
- refiner1 = mtri.UniformTriRefiner(triang1)
- refiner2 = mtri.UniformTriRefiner(triang2)
- fine_triang1 = refiner1.refine_triangulation(subdiv=1)
- fine_triang2 = refiner2.refine_triangulation(subdiv=1)
- assert_array_equal(fine_triang1.triangles, fine_triang2.triangles)
- def test_qhull_triangle_orientation():
- # github issue 4437.
- xi = np.linspace(-2, 2, 100)
- x, y = map(np.ravel, np.meshgrid(xi, xi))
- w = (x > y - 1) & (x < -1.95) & (y > -1.2)
- x, y = x[w], y[w]
- theta = np.radians(25)
- x1 = x*np.cos(theta) - y*np.sin(theta)
- y1 = x*np.sin(theta) + y*np.cos(theta)
- # Calculate Delaunay triangulation using Qhull.
- triang = mtri.Triangulation(x1, y1)
- # Neighbors returned by Qhull.
- qhull_neighbors = triang.neighbors
- # Obtain neighbors using own C++ calculation.
- triang._neighbors = None
- own_neighbors = triang.neighbors
- assert_array_equal(qhull_neighbors, own_neighbors)
- def test_trianalyzer_mismatched_indices():
- # github issue 4999.
- x = np.array([0., 1., 0.5, 0., 2.])
- y = np.array([0., 0., 0.5*np.sqrt(3.), -1., 1.])
- triangles = np.array([[0, 1, 2], [0, 1, 3], [1, 2, 4]], dtype=np.int32)
- mask = np.array([False, False, True], dtype=bool)
- triang = mtri.Triangulation(x, y, triangles, mask=mask)
- analyser = mtri.TriAnalyzer(triang)
- # numpy >= 1.10 raises a VisibleDeprecationWarning in the following line
- # prior to the fix.
- analyser._get_compressed_triangulation()
- def test_tricontourf_decreasing_levels():
- # github issue 5477.
- x = [0.0, 1.0, 1.0]
- y = [0.0, 0.0, 1.0]
- z = [0.2, 0.4, 0.6]
- plt.figure()
- with pytest.raises(ValueError):
- plt.tricontourf(x, y, z, [1.0, 0.0])
- def test_internal_cpp_api():
- # Following github issue 8197.
- from matplotlib import _tri # noqa: ensure lazy-loaded module *is* loaded.
- # C++ Triangulation.
- with pytest.raises(
- TypeError,
- match=r'function takes exactly 7 arguments \(0 given\)'):
- mpl._tri.Triangulation()
- with pytest.raises(
- ValueError, match=r'x and y must be 1D arrays of the same length'):
- mpl._tri.Triangulation([], [1], [[]], None, None, None, False)
- x = [0, 1, 1]
- y = [0, 0, 1]
- with pytest.raises(
- ValueError,
- match=r'triangles must be a 2D array of shape \(\?,3\)'):
- mpl._tri.Triangulation(x, y, [[0, 1]], None, None, None, False)
- tris = [[0, 1, 2]]
- with pytest.raises(
- ValueError,
- match=r'mask must be a 1D array with the same length as the '
- r'triangles array'):
- mpl._tri.Triangulation(x, y, tris, [0, 1], None, None, False)
- with pytest.raises(
- ValueError, match=r'edges must be a 2D array with shape \(\?,2\)'):
- mpl._tri.Triangulation(x, y, tris, None, [[1]], None, False)
- with pytest.raises(
- ValueError,
- match=r'neighbors must be a 2D array with the same shape as the '
- r'triangles array'):
- mpl._tri.Triangulation(x, y, tris, None, None, [[-1]], False)
- triang = mpl._tri.Triangulation(x, y, tris, None, None, None, False)
- with pytest.raises(
- ValueError,
- match=r'z array must have same length as triangulation x and y '
- r'array'):
- triang.calculate_plane_coefficients([])
- with pytest.raises(
- ValueError,
- match=r'mask must be a 1D array with the same length as the '
- r'triangles array'):
- triang.set_mask([0, 1])
- # C++ TriContourGenerator.
- with pytest.raises(
- TypeError,
- match=r'function takes exactly 2 arguments \(0 given\)'):
- mpl._tri.TriContourGenerator()
- with pytest.raises(
- ValueError,
- match=r'z must be a 1D array with the same length as the x and y '
- r'arrays'):
- mpl._tri.TriContourGenerator(triang, [1])
- z = [0, 1, 2]
- tcg = mpl._tri.TriContourGenerator(triang, z)
- with pytest.raises(
- ValueError, match=r'filled contour levels must be increasing'):
- tcg.create_filled_contour(1, 0)
- # C++ TrapezoidMapTriFinder.
- with pytest.raises(
- TypeError, match=r'function takes exactly 1 argument \(0 given\)'):
- mpl._tri.TrapezoidMapTriFinder()
- trifinder = mpl._tri.TrapezoidMapTriFinder(triang)
- with pytest.raises(
- ValueError, match=r'x and y must be array-like with same shape'):
- trifinder.find_many([0], [0, 1])
- def test_qhull_large_offset():
- # github issue 8682.
- x = np.asarray([0, 1, 0, 1, 0.5])
- y = np.asarray([0, 0, 1, 1, 0.5])
- offset = 1e10
- triang = mtri.Triangulation(x, y)
- triang_offset = mtri.Triangulation(x + offset, y + offset)
- assert len(triang.triangles) == len(triang_offset.triangles)
- def test_tricontour_non_finite_z():
- # github issue 10167.
- x = [0, 1, 0, 1]
- y = [0, 0, 1, 1]
- triang = mtri.Triangulation(x, y)
- plt.figure()
- with pytest.raises(ValueError, match='z array must not contain non-finite '
- 'values within the triangulation'):
- plt.tricontourf(triang, [0, 1, 2, np.inf])
- with pytest.raises(ValueError, match='z array must not contain non-finite '
- 'values within the triangulation'):
- plt.tricontourf(triang, [0, 1, 2, -np.inf])
- with pytest.raises(ValueError, match='z array must not contain non-finite '
- 'values within the triangulation'):
- plt.tricontourf(triang, [0, 1, 2, np.nan])
- with pytest.raises(ValueError, match='z must not contain masked points '
- 'within the triangulation'):
- plt.tricontourf(triang, np.ma.array([0, 1, 2, 3], mask=[1, 0, 0, 0]))
|