10000 Added 2 image tests and a non-image test. Miscellanous spelling corre… · matplotlib/matplotlib@14f05bb · GitHub
[go: up one dir, main page]

Skip to content

Commit 14f05bb

Browse files
committed
Added 2 image tests and a non-image test. Miscellanous spelling corrections.
1 parent cd45a80 commit 14f05bb

File tree

4 files changed

+232
-36
lines changed

4 files changed

+232
-36
lines changed
Loading
Loading

lib/matplotlib/tests/test_triangulation.py

Lines changed: 198 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from numpy.testing import assert_array_equal, assert_array_almost_equal,\
77
assert_array_less
88
from matplotlib.testing.decorators import image_comparison
9+
import matplotlib.cm as cm
910

1011

1112
def test_delaunay():
@@ -322,8 +323,8 @@ def gradient_quad(x, y):
322323
cubic_min_E = mtri.CubicTriInterpolator(triang, z)
323324
cubic_geom = mtri.CubicTriInterpolator(triang, z, kind='geom')
324325
zs = quad(xs, ys)
326+
diff_lin = np.abs(linear_interp(xs, ys) - zs)
325327
for interp in (cubic_min_E, cubic_geom):
326-
diff_lin = np.abs(linear_interp(xs, ys) - zs)
327328
diff_cubic = np.abs(interp(xs, ys) - zs)
328329
assert(np.max(diff_lin) >= 10.*np.max(diff_cubic))
329330
assert(np.dot(diff_lin, diff_lin) >=
@@ -461,7 +462,7 @@ def poisson_sparse_matrix(n, m):
461462 assert_array_almost_equal(np.dot(mat_dense, x), b)
462463

463464
# 2) Same matrix with inserting 2 rows - cols with null diag terms
464-
# (but still linked with the rest of the matrice by extra-diag terms)
465+
# (but still linked with the rest of the matrix by extra-diag terms)
465466
(i_zero, j_zero) = (12, 49)
466467
vals, rows, cols, _ = poisson_sparse_matrix(n, m)
467468
rows = rows + 1*(rows >= i_zero) + 1*(rows >= j_zero)
@@ -530,11 +531,10 @@ def test_triinterp_colinear():
530531
# These are not valid triangulations, but we try to deal with the
531532
# simplest violations (i. e. those handled by default TriFinder).
532533
#
533-
# Note that CubicTriInterpolator with kind='min_E' or 'geom' still pass a
534-
# linear patch test.
535-
# For the CubicTriInterpolator, we also test interpolation inside a
536-
# flat triangle, by forcing *tri_index* in a call to
537-
# :meth:`_interpolate_multikeys`
534+
# Note that the LinearTriInterpolator and the CubicTriInterpolator with
535+
# kind='min_E' or 'geom' still pass a linear patch test.
536+
# We also test interpolation inside a flat triangle, by forcing
537+
# *tri_index* in a call to :meth:`_interpolate_multikeys`.
538538

539539
delta = 0. # If +ve, triangulation is OK, if -ve triangulation invalid,
540540
# if zero have colinear points but should pass tests anyway.
@@ -584,6 +584,197 @@ def test_triinterp_colinear():
584584
assert_array_almost_equal(zs_target, zs)
585585

586586

587+
def test_triinterp_transformations():
588+
# 1) Testing that the interpolation scheme is invariant by rotation of the
589+
# whole figure.
590+
# Note: This test is non-trivial for a CubicTriInterpolator with
591+
# kind='min_E'. It does fail for a non-isotropic stiffness matrix E of
592+
# :class:`_ReducedHCT_Element` (tested with E=np.diag([1., 1., 1.])), and
593+
# provides a good test for :meth:`get_Kff_and_Ff`of the same class.
594+
#
595+
# 2) Also testing that the interpolation scheme is invariant by expansion
596+
# of the whole figure along one axis.
597+
n_angles = 20
598+
n_radii = 10
599+
min_radius = 0.15
600+
601+
def z(x, y):
602+
r1 = np.sqrt((0.5-x)**2 + (0.5-y)**2)
603+
theta1 = np.arctan2(0.5-x, 0.5-y)
604+
r2 = np.sqrt((-x-0.2)**2 + (-y-0.2)**2)
605+
theta2 = np.arctan2(-x-0.2, -y-0.2)
606+
z = -(2*(np.exp((r1/10)**2)-1)*30. * np.cos(7.*theta1) +
607+
(np.exp((r2/10)**2)-1)*30. * np.cos(11.*theta2) +
608+
0.7*(x**2 + y**2))
609+
return (np.max(z)-z)/(np.max(z)-np.min(z))
610+
611+
# First create the x and y coordinates of the points.
612+
radii = np.linspace(min_radius, 0.95, n_radii)
613+
angles = np.linspace(0 + n_angles, 2*np.pi + n_angles,
614+
n_angles, endpoint=False)
615+
angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1)
616+
angles[:, 1::2] += np.pi/n_angles
617+
x0 = (radii*np.cos(angles)).flatten()
618+
y0 = (radii*np.sin(angles)).flatten()
619+
triang0 = mtri.Triangulation(x0, y0) # Delaunay triangulation
620+
z0 = z(x0, y0)
621+
622+
# Then create the test points
623+
xs0 = np.linspace(-1., 1., 23)
624+
ys0 = np.linspace(-1., 1., 23)
625+
xs0, ys0 = np.meshgrid(xs0, ys0)
626+
xs0 = xs0.ravel()
627+
ys0 = ys0.ravel()
628+
629+
interp_z0 = {}
630+
for i_angle in range(2):
631+
# Rotating everything
632+
theta = 2*np.pi / n_angles * i_angle
633+
x = np.cos(theta)*x0 + np.sin(theta)*y0
634+
y = -np.sin(theta)*x0 + np.cos(theta)*y0
635+
xs = np.cos(theta)*xs0 + np.sin(theta)*ys0
636+
ys = -np.sin(theta)*xs0 + np.cos(theta)*ys0
637+
triang = mtri.Triangulation(x, y, triang0.triangles)
638+
linear_interp = mtri.LinearTriInterpolator(triang, z0)
639+
cubic_min_E = mtri.CubicTriInterpolator(triang, z0)
640+
cubic_geom = mtri.CubicTriInterpolator(triang, z0, kind='geom')
641+
dic_interp = {'lin': linear_interp,
642+
'min_E': cubic_min_E,
643+
'geom': cubic_geom}
644+
# Testing that the interpolation is invariant by rotation...
645+
for interp_key in ['lin', 'min_E', 'geom']:
646+
interp = dic_interp[interp_key]
647+
if i_angle == 0:
648+
interp_z0[interp_key] = interp(xs0, ys0) # storage
649+
else:
650+
interpz = interp(xs, ys)
651+
assert_array_almost_equal(interpz, interp_z0[interp_key])
652+
653+
scale_factor = 987654.3210
654+
for scaled_axis in ('x', 'y'):
655+
# Scaling everything (expansion along scaled_axis)
656+
if scaled_axis == 'x':
657+
x = scale_factor * x0
658+
y = y0
659+
xs = scale_factor * xs0
660+
ys = ys0
661+
else:
662+
x = x0
663+
y = scale_factor * y0
664+
xs = xs0
665+
ys = scale_factor * ys0
666+
triang = mtri.Triangulation(x, y, triang0.triangles)
667+
linear_interp = mtri.LinearTriInterpolator(triang, z0)
668+
cubic_min_E = mtri.CubicTriInterpolator(triang, z0)
669+
cubic_geom = mtri.CubicTriInterpolator(triang, z0, kind='geom')
670+
dic_interp = {'lin': linear_interp,
671+
'min_E': cubic_min_E,
672+
'geom': cubic_geom}
673+
# Testing that the interpolation is invariant by expansion along
674+
# 1 axis...
675+
for interp_key in ['lin', 'min_E', 'geom']:
676+
interpz = dic_interp[interp_key](xs, ys)
677+
assert_array_almost_equal(interpz, interp_z0[interp_key])
678+
679+
680+
@image_comparison(baseline_images=['tri_smooth_contouring'],
681+
extensions=['png'], remove_text=True)
682+
def test_tri_smooth_contouring():
683+
# Image comparison based on example tricontour_smooth_user.
684+
n_angles = 20
685+
n_radii = 10
686+
min_radius = 0.15
687+
688+
def z(x, y):
689+
r1 = np.sqrt((0.5-x)**2 + (0.5-y)**2)
690+
theta1 = np.arctan2(0.5-x, 0.5-y)
691+
r2 = np.sqrt((-x-0.2)**2 + (-y-0.2)**2)
692+
theta2 = np.arctan2(-x-0.2, -y-0.2)
693+
z = -(2*(np.exp((r1/10)**2)-1)*30. * np.cos(7.*theta1) +
694+
(np.exp((r2/10)**2)-1)*30. * np.cos(11.*theta2) +
695+
0.7*(x**2 + y**2))
696+
return (np.max(z)-z)/(np.max(z)-np.min(z))
697+
698+
# First create the x and y coordinates of the points.
699+
radii = np.linspace(min_radius, 0.95, n_radii)
700+
angles = np.linspace(0 + n_angles, 2*np.pi + n_angles,
701+
n_angles, endpoint=False)
702+
angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1)
703+
angles[:, 1::2] += np.pi/n_angles
704+
x0 = (radii*np.cos(angles)).flatten()
705+
y0 = (radii*np.sin(angles)).flatten()
706+
triang0 = mtri.Triangulation(x0, y0) # Delaunay triangulation
707+
z0 = z(x0, y0)
708+
xmid = x0[triang0.triangles].mean(axis=1)
709+
ymid = y0[triang0.triangles].mean(axis=1)
710+
mask = np.where(xmid*xmid + ymid*ymid < min_radius*min_radius, 1, 0)
711+
triang0.set_mask(mask)
712+
713+
# Then the plot
714+
plt.title("Refined tricontouring, subdiv=4")
715+
refiner = mtri.UniformTriRefiner(triang0)
716+
tri_refi, z_test_refi = refiner.refine_field(z0, subdiv=4)
717+
levels = np.arange(0., 1., 0.025)
718+
plt.triplot(triang0, lw=0.5, color='0.5')
719+
plt.tricontour(tri_refi, z_test_refi, levels=levels, colors="black")
720+
721+
722+
@image_comparison(baseline_images=['tri_smooth_gradient'],
723+
extensions=['png'], remove_text=True)
724+
def test_tri_smooth_gradient():
725+
# Image comparison based on example trigradient_demo.
726+
727+
def dipole_potential(x, y):
728+
""" An electric dipole potential V """
729+
r_sq = x**2 + y**2
730+
theta = np.arctan2(y, x)
731+
z = np.cos(theta)/r_sq
732+
return (np.max(z)-z) / (np.max(z)-np.min(z))
733+
734+
# Creating a Triangulation
735+
n_angles = 30
736+
n_radii = 10
737+
min_radius = 0.2
738+
radii = np.linspace(min_radius, 0.95, n_radii)
739+
angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False)
740+
angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1)
741+
angles[:, 1::2] += np.pi/n_angles
742+
x = (radii*np.cos(angles)).flatten()
743+
y = (radii*np.sin(angles)).flatten()
744+
V = dipole_potential(x, y)
745+
triang = mtri.Triangulation(x, y)
746+
xmid = x[triang.triangles].mean(axis=1)
747+
ymid = y[triang.triangles].mean(axis=1)
748+
mask = np.where(xmid*xmid + ymid*ymid < min_radius*min_radius, 1, 0)
749+
triang.set_mask(mask)
750+
751+
# Refine data - interpolates the electrical potential V
752+
refiner = mtri.UniformTriRefiner(triang)
753+
tri_refi, z_test_refi = refiner.refine_field(V, subdiv=3)
754+
755+
# Computes the electrical field (Ex, Ey) as gradient of -V
756+
tci = mtri.CubicTriInterpolator(triang, -V)
757+
(Ex, Ey) = tci.gradient(triang.x, triang.y)
758+
E_norm = np.sqrt(Ex**2 + Ey**2)
759+
760+
# Plot the triangulation, the potential iso-contours and the vector field
761+
plt.figure()
762+
plt.gca().set_aspect('equal')
763+
plt.triplot(triang, color='0.8')
764+
765+
levels = np.arange(0., 1., 0.01)
766+
cmap = cm.get_cmap(name='hot', lut=None)
767+
plt.tricontour(tri_refi, z_test_refi, levels=levels, cmap=cmap,
768+
linewidths=[2.0, 1.0, 1.0, 1.0])
769+
# Plots direction of the electrical vector field
770+
plt.quiver(triang.x, triang.y, Ex/E_norm, Ey/E_norm,
771+
units='xy', scale=10., zorder=3, color='blue',
772+
width=0.007, headwidth=3., headlength=4.)
773+
774+
plt.title('Gradient plot: an electrical dipole')
775+
plt.show()
776+
777+
587778
def test_tritools():
588779
# Tests TriAnalyzer.scale_factors on masked triangulation
589780
# Tests circle_ratios on equilateral and right-angled triangle.

0 commit comments

Comments
 (0)
0