Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 923f25c

Browse files
committed
Merge pull request matplotlib#3835 from tacaswell/single_axes_artist
Single axes artist
2 parents 403118d + c137a71 commit 923f25c

File tree

8 files changed

+80
-23
lines changed

8 files changed

+80
-23
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Prevent moving artists between Axes, Property-ify Artist.axes, deprecate Artist.{get,set}_axes
2+
``````````````````````````````````````````````````````````````````````````````````````````````
3+
4+
The reason this was done was to prevent adding an Artist that is
5+
already associated with an Axes to be moved/added to a different Axes.
6+
This was never supported as it causes havoc with the transform stack.
7+
The apparent support for this (as it did not raise an exception) was
8+
the source of multiple bug reports and questions on SO.
9+
10+
For almost all use-cases, the assignment of the axes to an artist should be
11+
taken care of by the axes as part of the ``Axes.add_*`` method, hence the
12+
deprecation {get,set}_axes.
13+
14+
Removing the ``set_axes`` method will also remove the 'axes' line from
15+
the ACCEPTS kwarg tables (assuming that the removal date gets here
16+
before that gets overhauled).

lib/matplotlib/artist.py

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import inspect
99
import matplotlib
1010
import matplotlib.cbook as cbook
11+
from matplotlib.cbook import mplDeprecation
1112
from matplotlib import docstring, rcParams
1213
from .transforms import (Bbox, IdentityTransform, TransformedBbox,
1314
TransformedPath, Transform)
@@ -77,6 +78,7 @@ class Artist(object):
7778
zorder = 0
7879

7980
def __init__(self):
81+
self._axes = None
8082
self.figure = None
8183

8284
self._transform = None
@@ -175,17 +177,43 @@ def set_axes(self, axes):
175177
Set the :class:`~matplotlib.axes.Axes` instance in which the
176178
artist resides, if any.
177179
180+
This has been deprecated in mpl 1.5, please use the
181+
axes property. Will be removed in 1.7 or 2.0.
182+
178183
ACCEPTS: an :class:`~matplotlib.axes.Axes` instance
179184
"""
185+
warnings.warn(_get_axes_msg, mplDeprecation, stacklevel=1)
180186
self.axes = axes
181187

182188
def get_axes(self):
183189
"""
184190
Return the :class:`~matplotlib.axes.Axes` instance the artist
185-
resides in, or *None*
191+
resides in, or *None*.
192+
193+
This has been deprecated in mpl 1.5, please use the
194+
axes property. Will be removed in 1.7 or 2.0.
186195
"""
196+
warnings.warn(_get_axes_msg, mplDeprecation, stacklevel=1)
187197
return self.axes
188198

199+
@property
200+
def axes(self):
201+
"""
202+
The :class:`~matplotlib.axes.Axes` instance the artist
203+
resides in, or *None*.
204+
"""
205+
return self._axes
206+
207+
@axes.setter
208+
def axes(self, new_axes):
209+
if self._axes is not None and new_axes != self._axes:
210+
raise ValueError("Can not reset the axes. You are "
211+
"probably trying to re-use an artist "
212+
"in more than one Axes which is not "
213+
"supported")
214+
self._axes = new_axes
215+
return new_axes
216+
189217
def get_window_extent(self, renderer):
190218
"""
191219
Get the axes bounding box in display space.
@@ -751,10 +779,13 @@ def update(self, props):
751779
changed = False
752780

753781
for k, v in six.iteritems(props):
754-
func = getattr(self, 'set_' + k, None)
755-
if func is None or not six.callable(func):
756-
raise AttributeError('Unknown property %s' % k)
757-
func(v)
782+
if k in ['axes']:
783+
setattr(self, k, v)
784+
else:
785+
func = getattr(self, 'set_' + k, None)
786+
if func is None or not six.callable(func):
787+
raise AttributeError('Unknown property %s' % k)
788+
func(v)
758789
changed = True
759790
self.eventson = store
760791
if changed:
@@ -1328,3 +1359,6 @@ def kwdoc(a):
13281359
return '\n'.join(ArtistInspector(a).pprint_setters(leadingspace=2))
13291360

13301361
docstring.interpd.update(Artist=kwdoc(Artist))
1362+
1363+
_get_axes_msg = """This has been deprecated in mpl 1.5, please use the
1364+
axes property. A removal date has not been set."""

lib/matplotlib/axes/_base.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,6 @@ def _makeline(self, x, y, kw, kwargs):
237237
# (can't use setdefault because it always evaluates
238238
# its second argument)
239239
seg = mlines.Line2D(x, y,
240-
axes=self.axes,
241240
**kw
242241
)
243242
self.set_lineprops(seg, **kwargs)
@@ -393,7 +392,8 @@ def __init__(self, fig, rect,
393392
else:
394393
self._position = mtransforms.Bbox.from_bounds(*rect)
395394
self._originalPosition = self._position.frozen()
396-
self.set_axes(self)
395+
# self.set_axes(self)
396+
self.axes = self
397397
self.set_aspect('auto')
398398
self._adjustable = 'box'
399399
self.set_anchor('C')
@@ -775,7 +775,7 @@ def _set_artist_props(self, a):
775775
if not a.is_transform_set():
776776
a.set_transform(self.transData)
777777

778-
a.set_axes(self)
778+
a.axes = self
779779

780780
def _gen_axes_patch(self):
781781
"""
@@ -1432,7 +1432,7 @@ def add_artist(self, a):
14321432
14331433
Returns the artist.
14341434
"""
1435-
a.set_axes(self)
1435+
a.axes = self
14361436
self.artists.append(a)
14371437
self._set_artist_props(a)
14381438
a.set_clip_path(self.patch)

lib/matplotlib/figure.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,11 @@ def __init__(self,
298298
Defaults to rc ``figure.autolayout``.
299299
"""
300300
Artist.__init__(self)
301-
301+
# remove the non-figure artist _axes property
302+
# as it makes no sense for a figure to be _in_ an axes
303+
# this is used by the property methods in the artist base class
304+
# which are over-ridden in this class
305+
del self._axes
302306
self.callbacks = cbook.CallbackRegistry()
303307

304308
if figsize is None:

lib/matplotlib/legend.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ def __init__(self, parent, handles, labels,
304304

305305
if isinstance(parent, Axes):
306306
self.isaxes = True
307-
self.set_axes(parent)
307+
self.axes = parent
308308
self.set_figure(parent.figure)
309309
elif isinstance(parent, Figure):
310310
self.isaxes = False
@@ -391,7 +391,9 @@ def _set_artist_props(self, a):
391391
"""
392392
a.set_figure(self.figure)
393393
if self.isaxes:
394-
a.set_axes(self.axes)
394+
# a.set_axes(self.axes)
395+
a.axes = self.axes
396+
395397
a.set_transform(self.get_transform())
396398

397399
def _set_loc(self, loc):

lib/matplotlib/lines.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -536,15 +536,17 @@ def get_window_extent(self, renderer):
536536
bbox = bbox.padded(ms)
537537
return bbox
538538

539-
def set_axes(self, ax):
540-
Artist.set_axes(self, ax)
539+
@Artist.axes.setter
540+
def axes(self, ax):
541+
# call the set method from the base-class property
542+
Artist.axes.fset(self, ax)
543+
# connect unit-related callbacks
541544
if ax.xaxis is not None:
542545
self._xcid = ax.xaxis.callbacks.connect('units',
543546
self.recache_always)
544547
if ax.yaxis is not None:
545548
self._ycid = ax.yaxis.callbacks.connect('units',
546549
self.recache_always)
547-
set_axes.__doc__ = Artist.set_axes.__doc__
548550

549551
def set_data(self, *args):
550552
"""

lib/matplotlib/tests/test_collections.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -407,14 +407,12 @@ def test_null_collection_datalim():
407407
def test_add_collection():
408408
# Test if data limits are unchanged by adding an empty collection.
409409
# Github issue #1490, pull #1497.
410-
ax = plt.axes()
411410
plt.figure()
412-
ax2 = plt.axes()
413-
coll = ax2.scatter([0, 1], [0, 1])
411+
ax = plt.axes()
412+
coll = ax.scatter([0, 1], [0, 1])
414413
ax.add_collection(coll)
415414
bounds = ax.dataLim.bounds
416-
coll = ax2.scatter([], [])
417-
ax.add_collection(coll)
415+
coll = ax.scatter([], [])
418416
assert_equal(ax.dataLim.bounds, bounds)
419417

420418

lib/mpl_toolkits/axes_grid1/inset_locator.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,20 +58,21 @@ def __call__(self, ax, renderer):
5858

5959
return bb
6060

61+
6162
from . import axes_size as Size
6263

6364

6465
class AnchoredSizeLocator(AnchoredLocatorBase):
6566
def __init__(self, bbox_to_anchor, x_size, y_size, loc,
6667
borderpad=0.5, bbox_transform=None):
67-
self.axes = None
68-
self.x_size = Size.from_any(x_size)
69-
self.y_size = Size.from_any(y_size)
7068

7169
super(AnchoredSizeLocator, self).__init__(bbox_to_anchor, None, loc,
7270
borderpad=borderpad,
7371
bbox_transform=bbox_transform)
7472

73+
self.x_size = Size.from_any(x_size)
74+
self.y_size = Size.from_any(y_size)
75+
7576
def get_extent(self, renderer):
7677

7778
x, y, w, h = self.get_bbox_to_anchor().bounds

0 commit comments

Comments
 (0)