diff --git a/doc/users/next_whats_new/2019-03-25-mplot3d-projection.rst b/doc/users/next_whats_new/2019-03-25-mplot3d-projection.rst new file mode 100644 index 000000000000..d60a4a921c45 --- /dev/null +++ b/doc/users/next_whats_new/2019-03-25-mplot3d-projection.rst @@ -0,0 +1,9 @@ +``Axes3D`` no longer distorts the 3d plot to match the 2d aspect ratio +---------------------------------------------------------------------- + +Plots made with :class:`~mpl_toolkits.mplot3d.axes3d.Axes3D` were previously +stretched to fit a square bounding box. As this stretching was done after +the projection from 3D to 2D, it resulted in distorted images if non-square +bounding boxes were used. + +As of this release, this no longer occurs. diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 430122a6315c..c3254bdc1b07 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -1499,9 +1499,9 @@ def apply_aspect(self, position=None): """ Adjust the Axes for a specified data aspect ratio. - Depending on `.get_adjustable` this will modify either the Axes box - (position) or the view limits. In the former case, `.get_anchor` - will affect the position. + Depending on `.get_adjustable` this will modify either the + Axes box (position) or the view limits. In the former case, + `~matplotlib.axes.Axes.get_anchor` will affect the position. Notes ----- diff --git a/lib/matplotlib/tests/baseline_images/test_collections/polycollection_close.png b/lib/matplotlib/tests/baseline_images/test_collections/polycollection_close.png index 20d5d3307ca9..bda2857d6321 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_collections/polycollection_close.png and b/lib/matplotlib/tests/baseline_images/test_collections/polycollection_close.png differ diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 4d87a2776db6..5b09e7454716 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -255,6 +255,20 @@ def tunit_edges(self, vals=None, M=None): (tc[7], tc[4])] return edges + def apply_aspect(self, position=None): + if position is None: + position = self.get_position(original=True) + + # in the superclass, we would go through and actually deal with axis + # scales and box/datalim. Those are all irrelevant - all we need to do + # is make sure our coordinate system is square. + figW, figH = self.get_figure().get_size_inches() + fig_aspect = figH / figW + box_aspect = 1 + pb = position.frozen() + pb1 = pb.shrunk_to_aspect(box_aspect, pb, fig_aspect) + self.set_position(pb1.anchored(self.get_anchor(), pb), 'active') + @artist.allow_rasterization def draw(self, renderer): # draw the background patch @@ -950,6 +964,9 @@ def get_proj(self): dist is the distance of the eye viewing point from the object point. """ + # chosen for similarity with the initial view before gh-8896 + pb_aspect = np.array([4, 4, 3]) / 3.5 + relev, razim = np.pi * self.elev/180, np.pi * self.azim/180 xmin, xmax = self.get_xlim3d() @@ -959,10 +976,10 @@ def get_proj(self): # transform to uniform world coordinates 0-1, 0-1, 0-1 worldM = proj3d.world_transformation(xmin, xmax, ymin, ymax, - zmin, zmax) + zmin, zmax, pb_aspect=pb_aspect) # look into the middle of the new coordinates - R = np.array([0.5, 0.5, 0.5]) + R = pb_aspect / 2 xp = R[0] + np.cos(razim) * np.cos(relev) * self.dist yp = R[1] + np.sin(razim) * np.cos(relev) * self.dist diff --git a/lib/mpl_toolkits/mplot3d/proj3d.py b/lib/mpl_toolkits/mplot3d/proj3d.py index 48b63f2e80f6..e2bb1cf69571 100644 --- a/lib/mpl_toolkits/mplot3d/proj3d.py +++ b/lib/mpl_toolkits/mplot3d/proj3d.py @@ -30,8 +30,20 @@ def _line2d_seg_dist(p1, p2, p0): def world_transformation(xmin, xmax, ymin, ymax, - zmin, zmax): - dx, dy, dz = (xmax-xmin), (ymax-ymin), (zmax-zmin) + zmin, zmax, pb_aspect=None): + """ + produce a matrix that scales homogenous coords in the specified ranges + to [0, 1], or [0, pb_aspect[i]] if the plotbox aspect ratio is specified + """ + dx = xmax - xmin + dy = ymax - ymin + dz = zmax - zmin + if pb_aspect is not None: + ax, ay, az = pb_aspect + dx /= ax + dy /= ay + dz /= az + return np.array([[1/dx, 0, 0, -xmin/dx], [0, 1/dy, 0, -ymin/dy], [0, 0, 1/dz, -zmin/dz], diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/axes3d_cla.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/axes3d_cla.png index 28c53105dbac..f93e18398c3e 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/axes3d_cla.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/axes3d_cla.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/axes3d_labelpad.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/axes3d_labelpad.png index a3585070b398..8d0499f7787d 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/axes3d_labelpad.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/axes3d_labelpad.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/axes3d_ortho.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/axes3d_ortho.png index d52add3671a9..e974aa95470c 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/axes3d_ortho.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/axes3d_ortho.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/axes3d_rotated.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/axes3d_rotated.png new file mode 100644 index 000000000000..0c79fd32e42c Binary files /dev/null and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/axes3d_rotated.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/bar3d.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/bar3d.png index 1e5c7c1a6615..d6520ca196d1 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/bar3d.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/bar3d.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/bar3d_notshaded.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/bar3d_notshaded.png index 54a515024a36..d718986b09dd 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/bar3d_notshaded.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/bar3d_notshaded.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/bar3d_shaded.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/bar3d_shaded.png index b1f7aa9a618c..c22f2a5671d3 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/bar3d_shaded.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/bar3d_shaded.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/contour3d.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/contour3d.png index ba603596e4b3..1d11116743b5 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/contour3d.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/contour3d.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/contourf3d.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/contourf3d.png index f38eaa4b91a1..33693b5e8ca2 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/contourf3d.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/contourf3d.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/contourf3d_fill.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/contourf3d_fill.png index 63dd67a186f6..3e34fc86556b 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/contourf3d_fill.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/contourf3d_fill.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/lines3d.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/lines3d.png index 7575e918e92c..b1118180ea11 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/lines3d.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/lines3d.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/mixedsubplot.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/mixedsubplot.png index fbfadeeb621d..0254e812d89d 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/mixedsubplot.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/mixedsubplot.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/plot_3d_from_2d.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/plot_3d_from_2d.png index 4475f5666511..89e72bfca05f 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/plot_3d_from_2d.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/plot_3d_from_2d.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/poly3dcollection_alpha.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/poly3dcollection_alpha.png index 6081c5a7e19c..9e8b27b949f9 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/poly3dcollection_alpha.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/poly3dcollection_alpha.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/poly3dcollection_closed.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/poly3dcollection_closed.png index 2ae2eac27151..9e8b27b949f9 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/poly3dcollection_closed.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/poly3dcollection_closed.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d.png index 130d5d21e56c..1875e4994545 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d_empty.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d_empty.png index df7185e00d86..2c888acb7c25 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d_empty.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d_empty.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d_masked.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d_masked.png index 1f12e7b4077d..cb0fae3c54f9 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d_masked.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d_masked.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d_pivot_middle.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d_pivot_middle.png index 6809caa61fd3..64601ae4d1c8 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d_pivot_middle.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d_pivot_middle.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d_pivot_tail.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d_pivot_tail.png index 1352d5bf8d5a..b026abbd272f 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d_pivot_tail.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/quiver3d_pivot_tail.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/scatter3d.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/scatter3d.png index 44e3adcfe98a..f0357508211c 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/scatter3d.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/scatter3d.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/scatter3d_color.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/scatter3d_color.png index 1ded1b338850..d594253b04b2 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/scatter3d_color.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/scatter3d_color.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/surface3d.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/surface3d.png index e9dfe54e3c1c..fcd05a708cfb 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/surface3d.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/surface3d.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/surface3d_shaded.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/surface3d_shaded.png index cb7cfef84297..65a31a7c3a22 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/surface3d_shaded.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/surface3d_shaded.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/text3d.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/text3d.png index 2264cffc4b0f..2956fd926b59 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/text3d.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/text3d.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/tricontour.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/tricontour.png index b71eaf6d9a86..7d8eb501601e 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/tricontour.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/tricontour.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/trisurf3d.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/trisurf3d.png index f69277c8d988..0e09672f5d83 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/trisurf3d.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/trisurf3d.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/trisurf3d_shaded.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/trisurf3d_shaded.png index 426baa4278fc..c403d1938eb1 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/trisurf3d_shaded.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/trisurf3d_shaded.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-alpha.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-alpha.png index 1b1348d0ab40..d47e8c54cbf9 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-alpha.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-alpha.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-edge-style.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-edge-style.png index fddbf5fe7353..8bbfc9e90f3e 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-edge-style.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-edge-style.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-named-colors.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-named-colors.png index 16758aae1428..20bf16a37f56 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-named-colors.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-named-colors.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-rgb-data.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-rgb-data.png index 2fa5ceb28398..938448857ec9 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-rgb-data.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-rgb-data.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-simple.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-simple.png index b23da1a36784..0a6e75b4c1a0 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-simple.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-simple.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-xyz.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-xyz.png index c69443628aaa..3e01b0129ff5 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-xyz.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/voxels-xyz.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/wireframe3d.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/wireframe3d.png index 28f1f1140beb..a1891222f2bb 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/wireframe3d.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/wireframe3d.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/wireframe3dzerocstride.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/wireframe3dzerocstride.png index 78ab297963ca..9a48b8b41188 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/wireframe3dzerocstride.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/wireframe3dzerocstride.png differ diff --git a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/wireframe3dzerorstride.png b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/wireframe3dzerorstride.png index 2ae4e2d32446..e55304caf197 100644 Binary files a/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/wireframe3dzerorstride.png and b/lib/mpl_toolkits/tests/baseline_images/test_mplot3d/wireframe3dzerorstride.png differ diff --git a/lib/mpl_toolkits/tests/test_mplot3d.py b/lib/mpl_toolkits/tests/test_mplot3d.py index 0b85ae5a50c7..11a6d07b7737 100644 --- a/lib/mpl_toolkits/tests/test_mplot3d.py +++ b/lib/mpl_toolkits/tests/test_mplot3d.py @@ -1,3 +1,5 @@ +import functools + import pytest from mpl_toolkits.mplot3d import Axes3D, axes3d, proj3d, art3d @@ -11,6 +13,10 @@ import numpy as np +mpl3d_image_comparison = functools.partial( + image_comparison, remove_text=True, style='default') + + def test_aspect_equal_error(): fig = plt.figure() ax = fig.add_subplot(111, projection='3d') @@ -18,7 +24,7 @@ def test_aspect_equal_error(): ax.set_aspect('equal') -@image_comparison(['bar3d.png'], remove_text=True) +@mpl3d_image_comparison(['bar3d.png']) def test_bar3d(): fig = plt.figure() ax = fig.add_subplot(111, projection='3d') @@ -30,13 +36,13 @@ def test_bar3d(): ax.bar(xs, ys, zs=z, zdir='y', align='edge', color=cs, alpha=0.8) -@image_comparison(['bar3d_shaded.png'], remove_text=True) +@mpl3d_image_comparison(['bar3d_shaded.png']) def test_bar3d_shaded(): x = np.arange(4) y = np.arange(5) x2d, y2d = np.meshgrid(x, y) x2d, y2d = x2d.ravel(), y2d.ravel() - z = x2d + y2d + z = x2d + y2d + 1 # Avoid triggering bug with zero-depth boxes. views = [(-60, 30), (30, 30), (30, -30), (120, -30)] fig = plt.figure(figsize=plt.figaspect(1 / len(views))) @@ -50,7 +56,7 @@ def test_bar3d_shaded(): fig.canvas.draw() -@image_comparison(['bar3d_notshaded.png'], remove_text=True) +@mpl3d_image_comparison(['bar3d_notshaded.png']) def test_bar3d_notshaded(): fig = plt.figure() ax = fig.add_subplot(111, projection='3d') @@ -90,7 +96,7 @@ def test_bar3d_lightsource(): np.testing.assert_array_equal(color, collection._facecolors3d[1::6]) -@image_comparison(['contour3d.png'], remove_text=True, style='mpl20') +@mpl3d_image_comparison(['contour3d.png']) def test_contour3d(): fig = plt.figure() ax = fig.gca(projection='3d') @@ -103,7 +109,7 @@ def test_contour3d(): ax.set_zlim(-100, 100) -@image_comparison(['contourf3d.png'], remove_text=True) +@mpl3d_image_comparison(['contourf3d.png']) def test_contourf3d(): fig = plt.figure() ax = fig.gca(projection='3d') @@ -116,7 +122,7 @@ def test_contourf3d(): ax.set_zlim(-100, 100) -@image_comparison(['contourf3d_fill.png'], remove_text=True) +@mpl3d_image_comparison(['contourf3d_fill.png']) def test_contourf3d_fill(): fig = plt.figure() ax = fig.gca(projection='3d') @@ -131,7 +137,7 @@ def test_contourf3d_fill(): ax.set_zlim(-1, 1) -@image_comparison(['tricontour.png'], remove_text=True, style='mpl20') +@mpl3d_image_comparison(['tricontour.png']) def test_tricontour(): fig = plt.figure() @@ -146,7 +152,7 @@ def test_tricontour(): ax.tricontourf(x, y, z) -@image_comparison(['lines3d.png'], remove_text=True) +@mpl3d_image_comparison(['lines3d.png']) def test_lines3d(): fig = plt.figure() ax = fig.gca(projection='3d') @@ -166,7 +172,7 @@ def test_plot_scalar(fig_test, fig_ref): ax2.plot(1, 1, "o") -@image_comparison(['mixedsubplot.png'], remove_text=True) +@mpl3d_image_comparison(['mixedsubplot.png']) def test_mixedsubplots(): def f(t): return np.cos(2*np.pi*t) * np.exp(-t) @@ -203,7 +209,7 @@ def test_tight_layout_text(fig_test, fig_ref): ax2.text(.5, .5, .5, s='some string') -@image_comparison(['scatter3d.png'], remove_text=True) +@mpl3d_image_comparison(['scatter3d.png']) def test_scatter3d(): fig = plt.figure() ax = fig.add_subplot(111, projection='3d') @@ -213,7 +219,7 @@ def test_scatter3d(): c='b', marker='^') -@image_comparison(['scatter3d_color.png'], remove_text=True) +@mpl3d_image_comparison(['scatter3d_color.png']) def test_scatter3d_color(): fig = plt.figure() ax = fig.add_subplot(111, projection='3d') @@ -223,7 +229,7 @@ def test_scatter3d_color(): color='b', marker='s') -@image_comparison(['plot_3d_from_2d.png'], remove_text=True) +@mpl3d_image_comparison(['plot_3d_from_2d.png'], tol=0.01) def test_plot_3d_from_2d(): fig = plt.figure() ax = fig.add_subplot(111, projection='3d') @@ -233,7 +239,7 @@ def test_plot_3d_from_2d(): ax.plot(xs, ys, zs=0, zdir='y') -@image_comparison(['surface3d.png'], remove_text=True) +@mpl3d_image_comparison(['surface3d.png']) def test_surface3d(): fig = plt.figure() ax = fig.gca(projection='3d') @@ -248,7 +254,7 @@ def test_surface3d(): fig.colorbar(surf, shrink=0.5, aspect=5) -@image_comparison(['surface3d_shaded.png'], remove_text=True) +@mpl3d_image_comparison(['surface3d_shaded.png']) def test_surface3d_shaded(): fig = plt.figure() ax = fig.gca(projection='3d') @@ -262,7 +268,7 @@ def test_surface3d_shaded(): ax.set_zlim(-1.01, 1.01) -@image_comparison(['text3d.png']) +@mpl3d_image_comparison(['text3d.png'], remove_text=False) def test_text3d(): fig = plt.figure() ax = fig.gca(projection='3d') @@ -286,7 +292,7 @@ def test_text3d(): ax.set_zlabel('Z axis') -@image_comparison(['trisurf3d.png'], remove_text=True, tol=0.03) +@mpl3d_image_comparison(['trisurf3d.png'], tol=0.03) def test_trisurf3d(): n_angles = 36 n_radii = 8 @@ -304,7 +310,7 @@ def test_trisurf3d(): ax.plot_trisurf(x, y, z, cmap=cm.jet, linewidth=0.2) -@image_comparison(['trisurf3d_shaded.png'], remove_text=True, tol=0.03) +@mpl3d_image_comparison(['trisurf3d_shaded.png'], tol=0.03) def test_trisurf3d_shaded(): n_angles = 36 n_radii = 8 @@ -322,7 +328,7 @@ def test_trisurf3d_shaded(): ax.plot_trisurf(x, y, z, color=[1, 0.5, 0], linewidth=0.2) -@image_comparison(['wireframe3d.png'], remove_text=True) +@mpl3d_image_comparison(['wireframe3d.png']) def test_wireframe3d(): fig = plt.figure() ax = fig.add_subplot(111, projection='3d') @@ -330,7 +336,7 @@ def test_wireframe3d(): ax.plot_wireframe(X, Y, Z, rcount=13, ccount=13) -@image_comparison(['wireframe3dzerocstride.png'], remove_text=True) +@mpl3d_image_comparison(['wireframe3dzerocstride.png']) def test_wireframe3dzerocstride(): fig = plt.figure() ax = fig.add_subplot(111, projection='3d') @@ -338,7 +344,7 @@ def test_wireframe3dzerocstride(): ax.plot_wireframe(X, Y, Z, rcount=13, ccount=0) -@image_comparison(['wireframe3dzerorstride.png'], remove_text=True) +@mpl3d_image_comparison(['wireframe3dzerorstride.png']) def test_wireframe3dzerorstride(): fig = plt.figure() ax = fig.add_subplot(111, projection='3d') @@ -364,7 +370,7 @@ def test_mixedsamplesraises(): ax.plot_surface(X, Y, Z, cstride=50, rcount=10) -@image_comparison(['quiver3d.png'], remove_text=True) +@mpl3d_image_comparison(['quiver3d.png']) def test_quiver3d(): fig = plt.figure() ax = fig.gca(projection='3d') @@ -379,7 +385,7 @@ def test_quiver3d(): ax.quiver(x, y, z, u, v, w, length=0.1, pivot='tip', normalize=True) -@image_comparison(['quiver3d_empty.png'], remove_text=True) +@mpl3d_image_comparison(['quiver3d_empty.png']) def test_quiver3d_empty(): fig = plt.figure() ax = fig.gca(projection='3d') @@ -394,7 +400,7 @@ def test_quiver3d_empty(): ax.quiver(x, y, z, u, v, w, length=0.1, pivot='tip', normalize=True) -@image_comparison(['quiver3d_masked.png'], remove_text=True) +@mpl3d_image_comparison(['quiver3d_masked.png']) def test_quiver3d_masked(): fig = plt.figure() ax = fig.gca(projection='3d') @@ -413,7 +419,7 @@ def test_quiver3d_masked(): ax.quiver(x, y, z, u, v, w, length=0.1, pivot='tip', normalize=True) -@image_comparison(['quiver3d_pivot_middle.png'], remove_text=True) +@mpl3d_image_comparison(['quiver3d_pivot_middle.png']) def test_quiver3d_pivot_middle(): fig = plt.figure() ax = fig.gca(projection='3d') @@ -428,7 +434,7 @@ def test_quiver3d_pivot_middle(): ax.quiver(x, y, z, u, v, w, length=0.1, pivot='middle', normalize=True) -@image_comparison(['quiver3d_pivot_tail.png'], remove_text=True) +@mpl3d_image_comparison(['quiver3d_pivot_tail.png']) def test_quiver3d_pivot_tail(): fig = plt.figure() ax = fig.gca(projection='3d') @@ -443,7 +449,7 @@ def test_quiver3d_pivot_tail(): ax.quiver(x, y, z, u, v, w, length=0.1, pivot='tail', normalize=True) -@image_comparison(['poly3dcollection_closed.png'], remove_text=True) +@mpl3d_image_comparison(['poly3dcollection_closed.png']) def test_poly3dcollection_closed(): fig = plt.figure() ax = fig.gca(projection='3d') @@ -465,7 +471,7 @@ def test_poly_collection_2d_to_3d_empty(): assert poly.get_paths() == [] -@image_comparison(['poly3dcollection_alpha.png'], remove_text=True) +@mpl3d_image_comparison(['poly3dcollection_alpha.png']) def test_poly3dcollection_alpha(): fig = plt.figure() ax = fig.gca(projection='3d') @@ -482,7 +488,7 @@ def test_poly3dcollection_alpha(): ax.add_collection3d(c2) -@image_comparison(['axes3d_labelpad.png']) +@mpl3d_image_comparison(['axes3d_labelpad.png'], remove_text=False) def test_axes3d_labelpad(): fig = plt.figure() ax = Axes3D(fig) @@ -502,7 +508,7 @@ def test_axes3d_labelpad(): tick.set_pad(tick.get_pad() - i * 5) -@image_comparison(['axes3d_cla.png']) +@mpl3d_image_comparison(['axes3d_cla.png'], remove_text=False) def test_axes3d_cla(): # fixed in pull request 4553 fig = plt.figure() @@ -511,6 +517,13 @@ def test_axes3d_cla(): ax.cla() # make sure the axis displayed is 3D (not 2D) +@mpl3d_image_comparison(['axes3d_rotated.png'], remove_text=False) +def test_axes3d_rotated(): + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1, projection='3d') + ax.view_init(90, 45) # look down, rotated. Should be square + + def test_plotsurface_1d_raises(): x = np.linspace(0.5, 10, num=100) y = np.linspace(0.5, 10, num=100) @@ -566,7 +579,7 @@ def _test_proj_draw_axes(M, s=1, *args, **kwargs): return fig, ax -@image_comparison(['proj3d_axes_cube.png'], remove_text=True, style='default') +@mpl3d_image_comparison(['proj3d_axes_cube.png']) def test_proj_axes_cube(): M = _test_proj_make_M() @@ -588,8 +601,7 @@ def test_proj_axes_cube(): ax.set_ylim(-0.2, 0.2) -@image_comparison(['proj3d_axes_cube_ortho.png'], - remove_text=True, style='default') +@mpl3d_image_comparison(['proj3d_axes_cube_ortho.png']) def test_proj_axes_cube_ortho(): E = np.array([200, 100, 100]) R = np.array([0, 0, 0]) @@ -638,8 +650,7 @@ def test_world(): [0, 0, 0, 1]]) -@image_comparison(['proj3d_lines_dists.png'], - remove_text=True, style='default') +@mpl3d_image_comparison(['proj3d_lines_dists.png']) def test_lines_dists(): fig, ax = plt.subplots(figsize=(4, 6), subplot_kw=dict(aspect='equal')) @@ -673,7 +684,7 @@ def test_autoscale(): assert ax.get_w_lims() == (0, 1, -.1, 1.1, -.4, 2.4) -@image_comparison(['axes3d_ortho.png'], style='default') +@mpl3d_image_comparison(['axes3d_ortho.png'], remove_text=False) def test_axes3d_ortho(): fig = plt.figure() ax = fig.gca(projection='3d') @@ -698,7 +709,7 @@ def test_invalid_axes_limits(setter, side, value): class TestVoxels: - @image_comparison(['voxels-simple.png'], remove_text=True) + @mpl3d_image_comparison(['voxels-simple.png']) def test_simple(self): fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) @@ -706,8 +717,7 @@ def test_simple(self): voxels = (x == y) | (y == z) ax.voxels(voxels) - @image_comparison(['voxels-edge-style.png'], - remove_text=True, style='default') + @mpl3d_image_comparison(['voxels-edge-style.png']) def test_edge_style(self): fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) @@ -718,7 +728,7 @@ def test_edge_style(self): # change the edge color of one voxel v[max(v.keys())].set_edgecolor('C2') - @image_comparison(['voxels-named-colors.png'], remove_text=True) + @mpl3d_image_comparison(['voxels-named-colors.png']) def test_named_colors(self): """Test with colors set to a 3d object array of strings.""" fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) @@ -731,7 +741,7 @@ def test_named_colors(self): colors[(x + z) < 10] = 'cyan' ax.voxels(voxels, facecolors=colors) - @image_comparison(['voxels-rgb-data.png'], remove_text=True) + @mpl3d_image_comparison(['voxels-rgb-data.png']) def test_rgb_data(self): """Test with colors set to a 4d float array of rgb data.""" fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) @@ -744,7 +754,7 @@ def test_rgb_data(self): colors[..., 2] = z / 9 ax.voxels(voxels, facecolors=colors) - @image_comparison(['voxels-alpha.png'], remove_text=True) + @mpl3d_image_comparison(['voxels-alpha.png']) def test_alpha(self): fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) @@ -762,7 +772,7 @@ def test_alpha(self): assert voxels[coord], "faces returned for absent voxel" assert isinstance(poly, art3d.Poly3DCollection) - @image_comparison(['voxels-xyz.png'], tol=0.01) + @mpl3d_image_comparison(['voxels-xyz.png'], tol=0.01, remove_text=False) def test_xyz(self): fig, ax = plt.subplots(subplot_kw={"projection": "3d"})