diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index ea8d569b50fe..0ac0839b0d64 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -1066,6 +1066,7 @@ def tk_window_focus(): default_test_modules = [ 'matplotlib.tests.test_agg', + 'matplotlib.tests.test_artist', 'matplotlib.tests.test_axes', 'matplotlib.tests.test_backend_svg', 'matplotlib.tests.test_backend_pgf', diff --git a/lib/matplotlib/artist.py b/lib/matplotlib/artist.py index 48a7b1f26361..96f78615c83f 100644 --- a/lib/matplotlib/artist.py +++ b/lib/matplotlib/artist.py @@ -231,7 +231,7 @@ def set_transform(self, t): ACCEPTS: :class:`~matplotlib.transforms.Transform` instance """ self._transform = t - self._transformSet = t is not None + self._transformSet = True self.pchanged() def get_transform(self): @@ -240,7 +240,7 @@ def get_transform(self): instance used by this artist. """ if self._transform is None: - self._transform = IdentityTransform() + self.set_transform(IdentityTransform()) elif (not isinstance(self._transform, Transform) and hasattr(self._transform, '_as_mpl_transform')): self._transform = self._transform._as_mpl_transform(self.axes) @@ -663,6 +663,7 @@ def update(self, props): store = self.eventson self.eventson = False changed = False + for k, v in props.iteritems(): func = getattr(self, 'set_' + k, None) if func is None or not callable(func): diff --git a/lib/matplotlib/streamplot.py b/lib/matplotlib/streamplot.py index bc611daa9675..d6090feea26a 100644 --- a/lib/matplotlib/streamplot.py +++ b/lib/matplotlib/streamplot.py @@ -65,6 +65,10 @@ def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None, mask = StreamMask(density) dmap = DomainMap(grid, mask) + # default to data coordinates + if transform is None: + transform = axes.transData + if color is None: color = axes._get_lines.color_cycle.next() diff --git a/lib/matplotlib/tests/test_artist.py b/lib/matplotlib/tests/test_artist.py new file mode 100644 index 000000000000..e60d7a8abe02 --- /dev/null +++ b/lib/matplotlib/tests/test_artist.py @@ -0,0 +1,81 @@ +from __future__ import print_function + +from matplotlib.testing.decorators import cleanup + +import matplotlib.pyplot as plt + +import matplotlib.patches as mpatches +import matplotlib.transforms as mtrans +import matplotlib.collections as mcollections + + +@cleanup +def test_patch_transform_of_none(): + # tests the behaviour of patches added to an Axes with various transform + # specifications + + ax = plt.axes() + ax.set_xlim([1, 3]) + ax.set_ylim([1, 3]) + + #draw an ellipse over data coord (2,2) by specifying device coords + xy_data = (2, 2) + xy_pix = ax.transData.transform_point(xy_data) + + # not providing a transform of None puts the ellipse in data coordinates + e = mpatches.Ellipse(xy_data, width=1, height=1, fc='yellow', alpha=0.5) + ax.add_patch(e) + assert e._transform == ax.transData + + # providing a transform of None puts the ellipse in device coordinates + e = mpatches.Ellipse(xy_pix, width=120, height=120, fc='coral', + transform=None, alpha=0.5) + ax.add_patch(e) + assert isinstance(e._transform, mtrans.IdentityTransform) + + # providing an IdentityTransform puts the ellipse in device coordinates + e = mpatches.Ellipse(xy_pix, width=100, height=100, + transform=mtrans.IdentityTransform(), alpha=0.5) + ax.add_patch(e) + assert isinstance(e._transform, mtrans.IdentityTransform) + + +@cleanup +def test_collection_transform_of_none(): + # tests the behaviour of collections added to an Axes with various + # transform specifications + + ax = plt.axes() + ax.set_xlim([1, 3]) + ax.set_ylim([1, 3]) + + #draw an ellipse over data coord (2,2) by specifying device coords + xy_data = (2, 2) + xy_pix = ax.transData.transform_point(xy_data) + + # not providing a transform of None puts the ellipse in data coordinates + e = mpatches.Ellipse(xy_data, width=1, height=1) + c = mcollections.PatchCollection([e], facecolor='yellow', alpha=0.5) + ax.add_collection(c) + # the collection should be in data coordinates + assert c.get_offset_transform() + c.get_transform() == ax.transData + + # providing a transform of None puts the ellipse in device coordinates + e = mpatches.Ellipse(xy_pix, width=120, height=120) + c = mcollections.PatchCollection([e], facecolor='coral', + alpha=0.5) + c.set_transform(None) + ax.add_collection(c) + assert isinstance(c.get_transform(), mtrans.IdentityTransform) + + # providing an IdentityTransform puts the ellipse in device coordinates + e = mpatches.Ellipse(xy_pix, width=100, height=100) + c = mcollections.PatchCollection([e], transform=mtrans.IdentityTransform(), + alpha=0.5) + ax.add_collection(c) + assert isinstance(c._transOffset, mtrans.IdentityTransform) + + +if __name__=='__main__': + import nose + nose.runmodule(argv=['-s','--with-doctest'], exit=False)