Skip to content

TST: Make proj3d tests into real tests #7310

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 1 addition & 87 deletions lib/mpl_toolkits/mplot3d/proj3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
import six
from six.moves import zip

from matplotlib.collections import LineCollection
from matplotlib.patches import Circle
import numpy as np
import numpy.linalg as linalg

Expand Down Expand Up @@ -69,27 +67,6 @@ def line2d_seg_dist(p1, p2, p0):

return d

def test_lines_dists():
import pylab
ax = pylab.gca()

xs, ys = (0,30), (20,150)
pylab.plot(xs, ys)
points = list(zip(xs, ys))
p0, p1 = points

xs, ys = (0,0,20,30), (100,150,30,200)
pylab.scatter(xs, ys)

dist = line2d_seg_dist(p0, p1, (xs[0], ys[0]))
dist = line2d_seg_dist(p0, p1, np.array((xs, ys)))
for x, y, d in zip(xs, ys, dist):
c = Circle((x, y), d, fill=0)
ax.add_patch(c)

pylab.xlim(-200, 200)
pylab.ylim(-200, 200)
pylab.show()

def mod(v):
"""3d vector length"""
Expand All @@ -105,12 +82,6 @@ def world_transformation(xmin, xmax,
[0,0,1.0/dz,-zmin/dz],
[0,0,0,1.0]])

def test_world():
xmin, xmax = 100, 120
ymin, ymax = -100, 100
zmin, zmax = 0.1, 0.2
M = world_transformation(xmin, xmax, ymin, ymax, zmin, zmax)
print(M)

def view_transformation(E, R, V):
n = (E - R)
Expand Down Expand Up @@ -218,69 +189,12 @@ def proj_trans_clip_points(points, M):
xs, ys, zs = list(zip(*points))
return proj_transform_clip(xs, ys, zs, M)

def test_proj_draw_axes(M, s=1):
import pylab
xs, ys, zs = [0, s, 0, 0], [0, 0, s, 0], [0, 0, 0, s]
txs, tys, tzs = proj_transform(xs, ys, zs, M)
o, ax, ay, az = (txs[0], tys[0]), (txs[1], tys[1]), \
(txs[2], tys[2]), (txs[3], tys[3])
lines = [(o, ax), (o, ay), (o, az)]

ax = pylab.gca()
linec = LineCollection(lines)
ax.add_collection(linec)
for x, y, t in zip(txs, tys, ['o', 'x', 'y', 'z']):
pylab.text(x, y, t)

def test_proj_make_M(E=None):
# eye point
E = E or np.array([1, -1, 2]) * 1000
#E = np.array([20,10,20])
R = np.array([1, 1, 1]) * 100
V = np.array([0, 0, 1])
viewM = view_transformation(E, R, V)
perspM = persp_transformation(100, -100)
M = np.dot(perspM, viewM)
return M

def test_proj():
import pylab
M = test_proj_make_M()

ts = ['%d' % i for i in [0,1,2,3,0,4,5,6,7,4]]
xs, ys, zs = [0,1,1,0,0, 0,1,1,0,0], [0,0,1,1,0, 0,0,1,1,0], \
[0,0,0,0,0, 1,1,1,1,1]
xs, ys, zs = [np.array(v)*300 for v in (xs, ys, zs)]
#
test_proj_draw_axes(M, s=400)
txs, tys, tzs = proj_transform(xs, ys, zs, M)
ixs, iys, izs = inv_transform(txs, tys, tzs, M)

pylab.scatter(txs, tys, c=tzs)
pylab.plot(txs, tys, c='r')
for x, y, t in zip(txs, tys, ts):
pylab.text(x, y, t)

pylab.xlim(-0.2, 0.2)
pylab.ylim(-0.2, 0.2)

pylab.show()

def rot_x(V, alpha):
Copy link
Member

@Kojoley Kojoley Oct 20, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is not used internally, exists since 2009 with an error and no one noticed that. Maybe it is better to remove it?

cosa, sina = np.cos(alpha), np.sin(alpha)
M1 = np.array([[1,0,0,0],
[0,cosa,-sina,0],
[0,sina,cosa,0],
[0,0,0,0]])
[0,0,0,1]])

return np.dot(M1, V)

def test_rot():
V = [1,0,0,1]
print(rot_x(V, np.pi/6))
V = [0,1,0,1]
print(rot_x(V, np.pi/6))


if __name__ == "__main__":
test_proj()
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
119 changes: 117 additions & 2 deletions lib/mpl_toolkits/tests/test_mplot3d.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import sys
import nose
from nose.tools import assert_raises
from mpl_toolkits.mplot3d import Axes3D, axes3d
from mpl_toolkits.mplot3d import Axes3D, axes3d, proj3d
from matplotlib import cm
from matplotlib.testing.decorators import image_comparison, cleanup
from matplotlib.collections import LineCollection
from matplotlib.patches import Circle
import matplotlib.pyplot as plt
import numpy as np

Expand Down Expand Up @@ -345,7 +347,120 @@ def test_plotsurface_1d_raises():
fig = plt.figure(figsize=(14,6))
ax = fig.add_subplot(1, 2, 1, projection='3d')
assert_raises(ValueError, ax.plot_surface, X, Y, z)



def _test_proj_make_M():
# eye point
E = np.array([1000, -1000, 2000])
R = np.array([100, 100, 100])
V = np.array([0, 0, 1])
viewM = proj3d.view_transformation(E, R, V)
perspM = proj3d.persp_transformation(100, -100)
M = np.dot(perspM, viewM)
return M


def test_proj_transform():
M = _test_proj_make_M()

xs = np.array([0, 1, 1, 0, 0, 0, 1, 1, 0, 0]) * 300.0
ys = np.array([0, 0, 1, 1, 0, 0, 0, 1, 1, 0]) * 300.0
zs = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1]) * 300.0

txs, tys, tzs = proj3d.proj_transform(xs, ys, zs, M)
ixs, iys, izs = proj3d.inv_transform(txs, tys, tzs, M)

np.testing.assert_almost_equal(ixs, xs)
np.testing.assert_almost_equal(iys, ys)
np.testing.assert_almost_equal(izs, zs)


def _test_proj_draw_axes(M, s=1, *args, **kwargs):
xs = [0, s, 0, 0]
ys = [0, 0, s, 0]
zs = [0, 0, 0, s]
txs, tys, tzs = proj3d.proj_transform(xs, ys, zs, M)
o, ax, ay, az = zip(txs, tys)
lines = [(o, ax), (o, ay), (o, az)]

fig, ax = plt.subplots(*args, **kwargs)
linec = LineCollection(lines)
ax.add_collection(linec)
for x, y, t in zip(txs, tys, ['o', 'x', 'y', 'z']):
ax.text(x, y, t)

return fig, ax


@image_comparison(baseline_images=['proj3d_axes_cube'], extensions=['png'],
remove_text=True, style='default')
def test_proj_axes_cube():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These might be good candidates for removing the text (so we do not test the tick labels)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point; tick labels are unimportant for these tests. I also switched it to the default style because I don't see why new test images need to use the classic style.

M = _test_proj_make_M()

ts = '0 1 2 3 0 4 5 6 7 4'.split()
xs = np.array([0, 1, 1, 0, 0, 0, 1, 1, 0, 0]) * 300.0
ys = np.array([0, 0, 1, 1, 0, 0, 0, 1, 1, 0]) * 300.0
zs = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1]) * 300.0

txs, tys, tzs = proj3d.proj_transform(xs, ys, zs, M)

fig, ax = _test_proj_draw_axes(M, s=400)

ax.scatter(txs, tys, c=tzs)
ax.plot(txs, tys, c='r')
for x, y, t in zip(txs, tys, ts):
ax.text(x, y, t)

ax.set_xlim(-0.2, 0.2)
ax.set_ylim(-0.2, 0.2)


def test_rot():
V = [1, 0, 0, 1]
rotated_V = proj3d.rot_x(V, np.pi / 6)
np.testing.assert_allclose(rotated_V, [1, 0, 0, 1])

V = [0, 1, 0, 1]
rotated_V = proj3d.rot_x(V, np.pi / 6)
np.testing.assert_allclose(rotated_V, [0, np.sqrt(3) / 2, 0.5, 1])


def test_world():
xmin, xmax = 100, 120
ymin, ymax = -100, 100
zmin, zmax = 0.1, 0.2
M = proj3d.world_transformation(xmin, xmax, ymin, ymax, zmin, zmax)
np.testing.assert_allclose(M,
[[5e-2, 0, 0, -5],
[0, 5e-3, 0, 5e-1],
[0, 0, 1e1, -1],
[0, 0, 0, 1]])


@image_comparison(baseline_images=['proj3d_lines_dists'], extensions=['png'],
remove_text=True, style='default')
def test_lines_dists():
fig, ax = plt.subplots(figsize=(4, 6), subplot_kw=dict(aspect='equal'))

xs = (0, 30)
ys = (20, 150)
ax.plot(xs, ys)
p0, p1 = zip(xs, ys)

xs = (0, 0, 20, 30)
ys = (100, 150, 30, 200)
ax.scatter(xs, ys)

dist = proj3d.line2d_seg_dist(p0, p1, (xs[0], ys[0]))
dist = proj3d.line2d_seg_dist(p0, p1, np.array((xs, ys)))
for x, y, d in zip(xs, ys, dist):
c = Circle((x, y), d, fill=0)
ax.add_patch(c)

ax.set_xlim(-50, 150)
ax.set_ylim(0, 300)


if __name__ == '__main__':
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)