diff --git a/.travis.yml b/.travis.yml index 4487f4af66d9..c92d8290229e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,4 +36,5 @@ script: after_failure: - tar cjf result_images.tar.bz2 result_images - travis-artifacts upload --path result_images.tar.bz2 - - echo https://s3.amazonaws.com/matplotlib-test-results/artifacts/${TRAVIS_BUILD_NUMBER}/${TRAVIS_JOB_NUMBER}/result_images.tar.bz2 \ No newline at end of file + - echo "The result images will only be uploaded if they are on the matplotlib/matplotlib repo - this is for security reasons to prevent arbitrary PRs echoing security details." + - echo https://s3.amazonaws.com/matplotlib-test-results/artifacts/${TRAVIS_BUILD_NUMBER}/${TRAVIS_JOB_NUMBER}/result_images.tar.bz2 diff --git a/lib/matplotlib/axes.py b/lib/matplotlib/axes.py index efc0e5746488..c1783d8be407 100644 --- a/lib/matplotlib/axes.py +++ b/lib/matplotlib/axes.py @@ -1474,10 +1474,7 @@ def add_collection(self, collection, autolim=True): if collection.get_clip_path() is None: collection.set_clip_path(self.patch) - if (autolim and - collection._paths is not None and - len(collection._paths) and - len(collection._offsets)): + if autolim: self.update_datalim(collection.get_datalim(self.transData)) collection._remove_method = lambda h: self.collections.remove(h) @@ -6834,8 +6831,8 @@ def quiver(self, *args, **kw): if not self._hold: self.cla() q = mquiver.Quiver(self, *args, **kw) - self.add_collection(q, False) - self.update_datalim(q.XY) + + self.add_collection(q, True) self.autoscale_view() return q quiver.__doc__ = mquiver.Quiver.quiver_doc @@ -6875,7 +6872,6 @@ def barbs(self, *args, **kw): self.cla() b = mquiver.Barbs(self, *args, **kw) self.add_collection(b) - self.update_datalim(b.get_offsets()) self.autoscale_view() return b diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index f7fd1c3f2cfb..13f9bfc24b69 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -188,13 +188,13 @@ def get_datalim(self, transData): # get_path_collection_extents handles nan but not masked arrays offsets.shape = (-1, 2) # Make it Nx2 - if paths: + if len(paths) and len(offsets): result = mpath.get_path_collection_extents( transform.frozen(), paths, self.get_transforms(), offsets, transOffset.frozen()) result = result.inverse_transformed(transData) else: - result = transforms.Bbox([[0, 0], [0, 0]]) + result = transforms.Bbox.null() return result def get_window_extent(self, renderer): @@ -1710,9 +1710,6 @@ def convert_mesh_to_triangles(self, meshWidth, meshHeight, coordinates): return triangles, colors - def get_datalim(self, transData): - return self._bbox - @allow_rasterization def draw(self, renderer): if not self.get_visible(): diff --git a/lib/matplotlib/quiver.py b/lib/matplotlib/quiver.py index e19f061b5a98..a5ba113dbfec 100644 --- a/lib/matplotlib/quiver.py +++ b/lib/matplotlib/quiver.py @@ -448,6 +448,15 @@ def _init(self): sn = max(8, min(25, math.sqrt(self.N))) self.width = 0.06 * self.span / sn + def get_datalim(self, transData): + trans = self.get_transform() + transOffset = self.get_offset_transform() + full_transform = (trans - transData) + (transOffset - transData) + XY = full_transform.transform(self.XY) + bbox = transforms.Bbox.null() + bbox.update_from_data_xy(XY, ignore=True) + return bbox + @allow_rasterization def draw(self, renderer): self._init() diff --git a/lib/matplotlib/streamplot.py b/lib/matplotlib/streamplot.py index 268c4de0dec0..e9aa56d406cc 100644 --- a/lib/matplotlib/streamplot.py +++ b/lib/matplotlib/streamplot.py @@ -168,9 +168,7 @@ def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None, lc.set_cmap(cmap) lc.set_norm(norm) axes.add_collection(lc) - - axes.update_datalim(((x.min(), y.min()), (x.max(), y.max()))) - axes.autoscale_view(tight=True) + axes.autoscale_view() ac = matplotlib.collections.PatchCollection(arrows) stream_container = StreamplotSet(lc, ac) diff --git a/lib/matplotlib/tests/baseline_images/test_pickle/multi_pickle.png b/lib/matplotlib/tests/baseline_images/test_pickle/multi_pickle.png index 0b99197be79c..5aaf97701e70 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_pickle/multi_pickle.png and b/lib/matplotlib/tests/baseline_images/test_pickle/multi_pickle.png differ diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index b56bfcb0ba23..654f57a11313 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -58,20 +58,6 @@ def test_formatter_ticker(): ax.set_xlabel( "x-label 005" ) ax.autoscale_view() -@cleanup -def test_add_collection(): - # Test if data limits are unchanged by adding an empty collection. - # Github issue #1490, pull #1497. - fig = matplotlib.figure.Figure() - fig2 = matplotlib.figure.Figure() - ax = fig.add_subplot(111) - ax2 = fig2.add_subplot(111) - coll = ax2.scatter([0, 1], [0, 1]) - ax.add_collection(coll) - bounds = ax.dataLim.bounds - coll = ax2.scatter([], []) - ax.add_collection(coll) - assert ax.dataLim.bounds == bounds @image_comparison(baseline_images=["formatter_large_small"]) def test_formatter_large_small(): @@ -81,6 +67,7 @@ def test_formatter_large_small(): y = [1e64, 1.1e64] ax.plot(x, y) + @image_comparison(baseline_images=["twin_axis_locaters_formatters"]) def test_twin_axis_locaters_formatters(): vals = np.linspace(0, 1, num=5, endpoint=True) diff --git a/lib/matplotlib/tests/test_collections.py b/lib/matplotlib/tests/test_collections.py index ce41e07cc4b7..074b3655a8d8 100644 --- a/lib/matplotlib/tests/test_collections.py +++ b/lib/matplotlib/tests/test_collections.py @@ -4,7 +4,7 @@ from nose.tools import assert_equal import numpy as np -from numpy.testing import assert_array_equal +from numpy.testing import assert_array_equal, assert_array_almost_equal import matplotlib.pyplot as plt import matplotlib.collections as mcollections @@ -396,9 +396,56 @@ def test_null_collection_datalim(): col = mcollections.PathCollection([]) col_data_lim = col.get_datalim(mtransforms.IdentityTransform()) assert_array_equal(col_data_lim.get_points(), - mtransforms.Bbox([[0, 0], [0, 0]]).get_points()) + mtransforms.Bbox.null().get_points()) +@cleanup +def test_add_collection(): + # Test if data limits are unchanged by adding an empty collection. + # Github issue #1490, pull #1497. + ax = plt.axes() + plt.figure() + ax2 = plt.axes() + coll = ax2.scatter([0, 1], [0, 1]) + ax.add_collection(coll) + bounds = ax.dataLim.bounds + coll = ax2.scatter([], []) + ax.add_collection(coll) + assert_equal(ax.dataLim.bounds, bounds) + + +@cleanup +def test_quiver_limits(): + ax = plt.axes() + x, y = np.arange(8), np.arange(10) + data = u = v = np.linspace(0, 10, 80).reshape(10, 8) + q = plt.quiver(x, y, u, v) + assert_equal(q.get_datalim(ax.transData).bounds, (0., 0., 7., 9.)) + + plt.figure() + ax = plt.axes() + x = np.linspace(-5, 10, 20) + y = np.linspace(-2, 4, 10) + y, x = np.meshgrid(y, x) + trans = mtransforms.Affine2D().translate(25, 32) + ax.transData + plt.quiver(x, y, np.sin(x), np.cos(y), transform=trans) + assert_equal(ax.dataLim.bounds, (20.0, 30.0, 15.0, 6.0)) + + +@cleanup +def test_barb_limits(): + ax = plt.axes() + x = np.linspace(-5, 10, 20) + y = np.linspace(-2, 4, 10) + y, x = np.meshgrid(y, x) + trans = mtransforms.Affine2D().translate(25, 32) + ax.transData + plt.barbs(x, y, np.sin(x), np.cos(y), transform=trans) + # The calculated bounds are approximately the bounds of the original data, + # this is because the entire path is taken into account when updating the + # datalim. + assert_array_almost_equal(ax.dataLim.bounds, (20, 30, 15, 6), + decimal=2) + if __name__ == '__main__': import nose nose.runmodule(argv=['-s', '--with-doctest'], exit=False) diff --git a/lib/matplotlib/tests/test_pickle.py b/lib/matplotlib/tests/test_pickle.py index 7889be2e92a4..3d2cda70b5b3 100644 --- a/lib/matplotlib/tests/test_pickle.py +++ b/lib/matplotlib/tests/test_pickle.py @@ -155,10 +155,14 @@ def test_complete(): plt.subplot(3, 3, 5) plt.pcolor(data) - plt.subplot(3, 3, 6) + ax = plt.subplot(3, 3, 6) + ax.set_xlim(0, 7) + ax.set_ylim(0, 9) plt.streamplot(x, y, u, v) - plt.subplot(3, 3, 7) + ax = plt.subplot(3, 3, 7) + ax.set_xlim(0, 7) + ax.set_ylim(0, 9) plt.quiver(x, y, u, v) plt.subplot(3, 3, 8) diff --git a/lib/matplotlib/tests/test_streamplot.py b/lib/matplotlib/tests/test_streamplot.py index 21e7f1b5d6ff..cc3b47e50263 100644 --- a/lib/matplotlib/tests/test_streamplot.py +++ b/lib/matplotlib/tests/test_streamplot.py @@ -1,6 +1,8 @@ import numpy as np +from numpy.testing import assert_array_almost_equal import matplotlib.pyplot as plt -from matplotlib.testing.decorators import image_comparison +from matplotlib.testing.decorators import image_comparison, cleanup +import matplotlib.transforms as mtransforms def velocity_field(): @@ -36,6 +38,21 @@ def test_masks_and_nans(): plt.streamplot(X, Y, U, V, color=U, cmap=plt.cm.Blues) +@cleanup +def test_streamplot_limits(): + ax = plt.axes() + x = np.linspace(-5, 10, 20) + y = np.linspace(-2, 4, 10) + y, x = np.meshgrid(y, x) + trans = mtransforms.Affine2D().translate(25, 32) + ax.transData + plt.barbs(x, y, np.sin(x), np.cos(y), transform=trans) + # The calculated bounds are approximately the bounds of the original data, + # this is because the entire path is taken into account when updating the + # datalim. + assert_array_almost_equal(ax.dataLim.bounds, (20, 30, 15, 6), + decimal=2) + + if __name__=='__main__': import nose nose.runmodule()