From c5d11472f8fc114571b3558a3ec6aa92dd96a281 Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Mon, 22 Apr 2013 08:58:34 +0100 Subject: [PATCH] Fixed failing bbox_inches='tight' case when a contour collection is empty. --- lib/matplotlib/collections.py | 11 +++-- lib/matplotlib/tests/test_collections.py | 56 ++++++++++++++---------- lib/matplotlib/transforms.py | 6 ++- 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index a513591501e4..71244c6d4bd4 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -186,10 +186,13 @@ def get_datalim(self, transData): # get_path_collection_extents handles nan but not masked arrays offsets.shape = (-1, 2) # Make it Nx2 - result = mpath.get_path_collection_extents( - transform.frozen(), paths, self.get_transforms(), - offsets, transOffset.frozen()) - result = result.inverse_transformed(transData) + if paths: + 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]]) return result def get_window_extent(self, renderer): diff --git a/lib/matplotlib/tests/test_collections.py b/lib/matplotlib/tests/test_collections.py index 7fac0a838c39..ce41e07cc4b7 100644 --- a/lib/matplotlib/tests/test_collections.py +++ b/lib/matplotlib/tests/test_collections.py @@ -2,9 +2,13 @@ Tests specific to the collections module. """ -import nose.tools +from nose.tools import assert_equal import numpy as np +from numpy.testing import assert_array_equal + import matplotlib.pyplot as plt +import matplotlib.collections as mcollections +import matplotlib.transforms as mtransforms from matplotlib.collections import EventCollection from matplotlib.testing.decorators import cleanup, image_comparison @@ -81,7 +85,7 @@ def test__EventCollection__get_orientation(): orientation ''' _, coll, props = generate_EventCollection_plot() - nose.tools.assert_equal(props['orientation'], coll.get_orientation()) + assert_equal(props['orientation'], coll.get_orientation()) @cleanup @@ -91,7 +95,7 @@ def test__EventCollection__is_horizontal(): orientation ''' _, coll, _ = generate_EventCollection_plot() - nose.tools.assert_equal(True, coll.is_horizontal()) + assert_equal(True, coll.is_horizontal()) @cleanup @@ -100,7 +104,7 @@ def test__EventCollection__get_linelength(): check to make sure the default linelength matches the input linelength ''' _, coll, props = generate_EventCollection_plot() - nose.tools.assert_equal(props['linelength'], coll.get_linelength()) + assert_equal(props['linelength'], coll.get_linelength()) @cleanup @@ -109,7 +113,7 @@ def test__EventCollection__get_lineoffset(): check to make sure the default lineoffset matches the input lineoffset ''' _, coll, props = generate_EventCollection_plot() - nose.tools.assert_equal(props['lineoffset'], coll.get_lineoffset()) + assert_equal(props['lineoffset'], coll.get_lineoffset()) @cleanup @@ -118,7 +122,7 @@ def test__EventCollection__get_linestyle(): check to make sure the default linestyle matches the input linestyle ''' _, coll, _ = generate_EventCollection_plot() - nose.tools.assert_equal(coll.get_linestyle(), [(None, None)]) + assert_equal(coll.get_linestyle(), [(None, None)]) @cleanup @@ -213,8 +217,8 @@ def test__EventCollection__switch_orientation(): splt, coll, props = generate_EventCollection_plot() new_orientation = 'vertical' coll.switch_orientation() - nose.tools.assert_equal(new_orientation, coll.get_orientation()) - nose.tools.assert_equal(False, coll.is_horizontal()) + assert_equal(new_orientation, coll.get_orientation()) + assert_equal(False, coll.is_horizontal()) new_positions = coll.get_positions() check_segments(coll, new_positions, @@ -236,8 +240,8 @@ def test__EventCollection__switch_orientation_2x(): coll.switch_orientation() coll.switch_orientation() new_positions = coll.get_positions() - nose.tools.assert_equal(props['orientation'], coll.get_orientation()) - nose.tools.assert_equal(True, coll.is_horizontal()) + assert_equal(props['orientation'], coll.get_orientation()) + assert_equal(True, coll.is_horizontal()) np.testing.assert_array_equal(props['positions'], new_positions) check_segments(coll, new_positions, @@ -255,8 +259,8 @@ def test__EventCollection__set_orientation(): splt, coll, props = generate_EventCollection_plot() new_orientation = 'vertical' coll.set_orientation(new_orientation) - nose.tools.assert_equal(new_orientation, coll.get_orientation()) - nose.tools.assert_equal(False, coll.is_horizontal()) + assert_equal(new_orientation, coll.get_orientation()) + assert_equal(False, coll.is_horizontal()) check_segments(coll, props['positions'], props['linelength'], @@ -275,7 +279,7 @@ def test__EventCollection__set_linelength(): splt, coll, props = generate_EventCollection_plot() new_linelength = 15 coll.set_linelength(new_linelength) - nose.tools.assert_equal(new_linelength, coll.get_linelength()) + assert_equal(new_linelength, coll.get_linelength()) check_segments(coll, props['positions'], new_linelength, @@ -293,7 +297,7 @@ def test__EventCollection__set_lineoffset(): splt, coll, props = generate_EventCollection_plot() new_lineoffset = -5. coll.set_lineoffset(new_lineoffset) - nose.tools.assert_equal(new_lineoffset, coll.get_lineoffset()) + assert_equal(new_lineoffset, coll.get_lineoffset()) check_segments(coll, props['positions'], props['linelength'], @@ -311,7 +315,7 @@ def test__EventCollection__set_linestyle(): splt, coll, _ = generate_EventCollection_plot() new_linestyle = 'dashed' coll.set_linestyle(new_linestyle) - nose.tools.assert_equal(coll.get_linestyle(), [(0, (6.0, 6.0))]) + assert_equal(coll.get_linestyle(), [(0, (6.0, 6.0))]) splt.set_title('EventCollection: set_linestyle') @@ -323,7 +327,7 @@ def test__EventCollection__set_linewidth(): splt, coll, _ = generate_EventCollection_plot() new_linewidth = 5 coll.set_linewidth(new_linewidth) - nose.tools.assert_equal(coll.get_linewidth(), new_linewidth) + assert_equal(coll.get_linewidth(), new_linewidth) splt.set_title('EventCollection: set_linewidth') @@ -362,10 +366,10 @@ def check_segments(coll, positions, linelength, lineoffset, orientation): # test to make sure each segment is correct for i, segment in enumerate(segments): - nose.tools.assert_equal(segment[0, pos1], lineoffset + linelength / 2.) - nose.tools.assert_equal(segment[1, pos1], lineoffset - linelength / 2.) - nose.tools.assert_equal(segment[0, pos2], positions[i]) - nose.tools.assert_equal(segment[1, pos2], positions[i]) + assert_equal(segment[0, pos1], lineoffset + linelength / 2.) + assert_equal(segment[1, pos1], lineoffset - linelength / 2.) + assert_equal(segment[0, pos2], positions[i]) + assert_equal(segment[1, pos2], positions[i]) def check_allprop(values, target): @@ -375,7 +379,7 @@ def check_allprop(values, target): note: this is not a test, it is used by tests ''' for value in values: - nose.tools.assert_equal(value, target) + assert_equal(value, target) def check_allprop_array(values, target): @@ -387,6 +391,14 @@ def check_allprop_array(values, target): for value in values: np.testing.assert_array_equal(value, target) -if __name__ == '_main_': + +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()) + + +if __name__ == '__main__': import nose nose.runmodule(argv=['-s', '--with-doctest'], exit=False) diff --git a/lib/matplotlib/transforms.py b/lib/matplotlib/transforms.py index c95285cb11b0..e2ff4ba3222d 100644 --- a/lib/matplotlib/transforms.py +++ b/lib/matplotlib/transforms.py @@ -772,7 +772,11 @@ def __init__(self, points, **kwargs): :meth:`from_bounds` and :meth:`from_extents`. """ BboxBase.__init__(self, **kwargs) - self._points = np.asarray(points, np.float_) + points = np.asarray(points, np.float_) + if points.shape != (2, 2): + raise ValueError('Bbox points must be of the form ' + '"[[x0, y0], [x1, y1]]".') + self._points = points self._minpos = np.array([0.0000001, 0.0000001]) self._ignore = True # it is helpful in some contexts to know if the bbox is a