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

Skip to content

Commit bc20617

Browse files
committed
Simplify axes and axis clearing, sharing, and aspect ratio control
- Axis sharing works across figures. - The "box-forced" adjustable is no longer needed. - Sharing both axes requires the use of "box", not "datalim". - A new "share" kwarg triggers synchronized setting of aspect ratio and adjustable in Axes within shared axis groups. - Added a test for axis sharing with aspect ratio setting. - Fixed and updated skew_rects test. Fix PEP8 errors Minor fixups from qlogic review Single extra space removed to placate PEP 8. Handle all Line2D properties for gridlines. This is required for consistency with the present grid() documentation and behavior, but the list of allowed properties should be trimmed. PEP 8 again Back out changes related to making cla() less inefficient
1 parent c229bd5 commit bc20617

File tree

8 files changed

+1722
-1673
lines changed

8 files changed

+1722
-1673
lines changed

lib/matplotlib/axes/_base.py

Lines changed: 46 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -490,25 +490,15 @@ def __init__(self, fig, rect,
490490
self._originalPosition = self._position.frozen()
491491
# self.set_axes(self)
492492
self.axes = self
493-
self.set_aspect('auto')
493+
self._aspect = 'auto'
494494
self._adjustable = 'box'
495-
self.set_anchor('C')
495+
self._anchor = 'C'
496496
self._sharex = sharex
497497
self._sharey = sharey
498498
if sharex is not None:
499499
self._shared_x_axes.join(self, sharex)
500-
if sharex._adjustable == 'box':
501-
sharex._adjustable = 'datalim'
502-
# warnings.warn(
503-
# 'shared axes: "adjustable" is being changed to "datalim"')
504-
self._adjustable = 'datalim'
505500
if sharey is not None:
506501
self._shared_y_axes.join(self, sharey)
507-
if sharey._adjustable == 'box':
508-
sharey._adjustable = 'datalim'
509-
# warnings.warn(
510-
# 'shared axes: "adjustable" is being changed to "datalim"')
511-
self._adjustable = 'datalim'
512502
self.set_label(label)
513503
self.set_figure(fig)
514504

@@ -532,6 +522,7 @@ def __init__(self, fig, rect,
532522

533523
self._connected = {} # a dict from events to (id, func)
534524
self.cla()
525+
535526
# funcs used to format x and y - fall back on major formatters
536527
self.fmt_xdata = None
537528
self.fmt_ydata = None
@@ -633,8 +624,7 @@ def set_figure(self, fig):
633624

634625
def _set_lim_and_transforms(self):
635626
"""
636-
set the *dataLim* and *viewLim*
637-
:class:`~matplotlib.transforms.Bbox` attributes and the
627+
set the *_xaxis_transform*, *_yaxis_transform*,
638628
*transScale*, *transData*, *transLimits* and *transAxes*
639629
transformations.
640630
@@ -984,21 +974,22 @@ def cla(self):
984974

985975
self.xaxis.cla()
986976
self.yaxis.cla()
977+
987978
for name, spine in six.iteritems(self.spines):
988979
spine.cla()
989980

990981
self.ignore_existing_data_limits = True
991982
self.callbacks = cbook.CallbackRegistry()
992983

993984
if self._sharex is not None:
994-
# major and minor are class instances with
985+
# major and minor are axis.Ticker class instances with
995986
# locator and formatter attributes
996987
self.xaxis.major = self._sharex.xaxis.major
997988
self.xaxis.minor = self._sharex.xaxis.minor
998989
x0, x1 = self._sharex.get_xlim()
999990
self.set_xlim(x0, x1, emit=False, auto=None)
1000991
self.xaxis._scale = mscale.scale_factory(
1001-
self._sharex.xaxis.get_scale(), self.xaxis)
992+
self._sharex.xaxis.get_scale(), self.xaxis)
1002993
else:
1003994
self.xaxis._set_scale('linear')
1004995
try:
@@ -1012,14 +1003,13 @@ def cla(self):
10121003
y0, y1 = self._sharey.get_ylim()
10131004
self.set_ylim(y0, y1, emit=False, auto=None)
10141005
self.yaxis._scale = mscale.scale_factory(
1015-
self._sharey.yaxis.get_scale(), self.yaxis)
1006+
self._sharey.yaxis.get_scale(), self.yaxis)
10161007
else:
10171008
self.yaxis._set_scale('linear')
10181009
try:
10191010
self.set_ylim(0, 1)
10201011
except TypeError:
10211012
pass
1022-
10231013
# update the minor locator for x and y axis based on rcParams
10241014
if (rcParams['xtick.minor.visible']):
10251015
self.xaxis.set_minor_locator(mticker.AutoMinorLocator())
@@ -1262,7 +1252,7 @@ def hold(self, b=None):
12621252
def get_aspect(self):
12631253
return self._aspect
12641254

1265-
def set_aspect(self, aspect, adjustable=None, anchor=None):
1255+
def set_aspect(self, aspect, adjustable=None, anchor=None, share=False):
12661256
"""
12671257
Set the aspect of the axis scaling, i.e. the ratio of y-unit to x-unit.
12681258
@@ -1281,7 +1271,7 @@ def set_aspect(self, aspect, adjustable=None, anchor=None):
12811271
aspect='equal'.
12821272
======== ================================================
12831273
1284-
adjustable : None or ['box' | 'datalim' | 'box-forced'], optional
1274+
adjustable : None or ['box' | 'datalim'], optional
12851275
If not ``None``, this defines which parameter will be adjusted to
12861276
meet the required aspect. See `.set_adjustable` for further
12871277
details.
@@ -1317,16 +1307,25 @@ def set_aspect(self, aspect, adjustable=None, anchor=None):
13171307
else:
13181308
self._aspect = float(aspect) # raise ValueError if necessary
13191309

1320-
if adjustable is not None:
1321-
self.set_adjustable(adjustable)
1310+
if share and self in self._shared_x_axes:
1311+
for ax in self._shared_x_axes.get_siblings(self):
1312+
ax._aspect = aspect
1313+
if share and self in self._shared_y_axes:
1314+
for ax in self._shared_y_axes.get_siblings(self):
1315+
ax._aspect = aspect
1316+
1317+
if adjustable is None:
1318+
adjustable = self._adjustable
1319+
self.set_adjustable(adjustable, share=share) # Handle sharing.
1320+
13221321
if anchor is not None:
13231322
self.set_anchor(anchor)
13241323
self.stale = True
13251324

13261325
def get_adjustable(self):
13271326
return self._adjustable
13281327

1329-
def set_adjustable(self, adjustable):
1328+
def set_adjustable(self, adjustable, share=False):
13301329
"""
13311330
Define which parameter the Axes will change to achieve a given aspect.
13321331
@@ -1337,26 +1336,28 @@ def set_adjustable(self, adjustable):
13371336
============ =====================================
13381337
'box' change the physical size of the Axes
13391338
'datalim' change xlim or ylim
1340-
'box-forced' same as 'box', but axes can be shared
13411339
============ =====================================
13421340
1343-
'box' does not allow axes sharing, as this can cause
1344-
unintended side effect. For cases when sharing axes is
1345-
fine, use 'box-forced'.
1346-
13471341
..
1348-
ACCEPTS: [ 'box' | 'datalim' | 'box-forced']
1342+
ACCEPTS: [ 'box' | 'datalim']
13491343
13501344
See Also
13511345
--------
13521346
matplotlib.axes.Axes.set_aspect
13531347
for a description of aspect handling.
13541348
"""
1349+
# FIXME: add box-forced deprecation
13551350
if adjustable in ('box', 'datalim', 'box-forced'):
1356-
if self in self._shared_x_axes or self in self._shared_y_axes:
1357-
if adjustable == 'box':
1351+
if self in self._shared_x_axes and self in self._shared_y_axes:
1352+
if adjustable == 'datalim':
13581353
raise ValueError(
1359-
'adjustable must be "datalim" for shared axes')
1354+
'adjustable must be "box" when both axes are shared')
1355+
if share and self in self._shared_x_axes:
1356+
for ax in self._shared_x_axes.get_siblings(self):
1357+
ax._adjustable = adjustable
1358+
if share and self in self._shared_y_axes:
1359+
for ax in self._shared_y_axes.get_siblings(self):
1360+
ax._adjustable = adjustable
13601361
self._adjustable = adjustable
13611362
else:
13621363
raise ValueError('argument must be "box", or "datalim"')
@@ -1508,14 +1509,6 @@ def apply_aspect(self, position=None):
15081509
else:
15091510
A = aspect
15101511

1511-
# Ensure at drawing time that any Axes involved in axis-sharing
1512-
# does not have its position changed.
1513-
if self in self._shared_x_axes or self in self._shared_y_axes:
1514-
if self._adjustable == 'box':
1515-
self._adjustable = 'datalim'
1516-
warnings.warn(
1517-
'shared axes: "adjustable" is being changed to "datalim"')
1518-
15191512
figW, figH = self.get_figure().get_size_inches()
15201513
fig_aspect = figH / figW
15211514
if self._adjustable in ['box', 'box-forced']:
@@ -1573,23 +1566,24 @@ def apply_aspect(self, position=None):
15731566
xm = 0
15741567
ym = 0
15751568

1576-
changex = (self in self._shared_y_axes and
1577-
self not in self._shared_x_axes)
1578-
changey = (self in self._shared_x_axes and
1579-
self not in self._shared_y_axes)
1580-
if changex and changey:
1581-
warnings.warn("adjustable='datalim' cannot work with shared "
1582-
"x and y axes")
1583-
return
1584-
if changex:
1569+
shared_x = self in self._shared_x_axes
1570+
shared_y = self in self._shared_y_axes
1571+
# Not sure whether we need this check:
1572+
if shared_x and shared_y:
1573+
raise RuntimeError("adjustable='datalim' is not allowed when both"
1574+
" axes are shared.")
1575+
1576+
# If y is shared, then we are only allowed to change x, etc.
1577+
if shared_y:
15851578
adjust_y = False
15861579
else:
15871580
if xmarg > xm and ymarg > ym:
15881581
adjy = ((Ymarg > 0 and y_expander < 0) or
15891582
(Xmarg < 0 and y_expander > 0))
15901583
else:
15911584
adjy = y_expander > 0
1592-
adjust_y = changey or adjy # (Ymarg > xmarg)
1585+
adjust_y = shared_x or adjy # (Ymarg > xmarg)
1586+
15931587
if adjust_y:
15941588
yc = 0.5 * (ymin + ymax)
15951589
y0 = yc - Ysize / 2.0
@@ -4189,9 +4183,9 @@ def twiny(self):
41894183
return ax2
41904184

41914185
def get_shared_x_axes(self):
4192-
"""Return a copy of the shared axes Grouper object for x axes."""
4186+
'Return a reference to the shared axes Grouper object for x axes'
41934187
return self._shared_x_axes
41944188

41954189
def get_shared_y_axes(self):
4196-
"""Return a copy of the shared axes Grouper object for y axes."""
4190+
'Return a reference to the shared axes Grouper object for y axes'
41974191
return self._shared_y_axes

0 commit comments

Comments
 (0)