From 74f65263cdfda7f0d84f0ab8cbf9515e10aa107d Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Mon, 12 Jun 2017 07:31:16 -1000 Subject: [PATCH 1/7] Simplify axes and axis clearing, sharing, and aspect ratio control - Most of the unnecessary calls to Axis.cla() have been removed. - 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. --- lib/matplotlib/axes/_base.py | 152 +- lib/matplotlib/axis.py | 106 +- lib/matplotlib/scale.py | 9 +- lib/matplotlib/spines.py | 8 +- .../baseline_images/test_skew/skew_rects.pdf | Bin 7470 -> 7923 bytes .../baseline_images/test_skew/skew_rects.png | Bin 31973 -> 22740 bytes .../baseline_images/test_skew/skew_rects.svg | 3118 ++++++++--------- lib/matplotlib/tests/test_axes.py | 42 + lib/matplotlib/tests/test_skew.py | 12 +- 9 files changed, 1750 insertions(+), 1697 deletions(-) diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 4462cd620ce6..ac89374f27c8 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -488,25 +488,15 @@ def __init__(self, fig, rect, self._originalPosition = self._position.frozen() # self.set_axes(self) self.axes = self - self.set_aspect('auto') + self._aspect = 'auto' self._adjustable = 'box' - self.set_anchor('C') + self._anchor = 'C' self._sharex = sharex self._sharey = sharey if sharex is not None: self._shared_x_axes.join(self, sharex) - if sharex._adjustable == 'box': - sharex._adjustable = 'datalim' - # warnings.warn( - # 'shared axes: "adjustable" is being changed to "datalim"') - self._adjustable = 'datalim' if sharey is not None: self._shared_y_axes.join(self, sharey) - if sharey._adjustable == 'box': - sharey._adjustable = 'datalim' - # warnings.warn( - # 'shared axes: "adjustable" is being changed to "datalim"') - self._adjustable = 'datalim' self.set_label(label) self.set_figure(fig) @@ -537,7 +527,11 @@ def __init__(self, fig, rect, self._hold = True self._connected = {} # a dict from events to (id, func) - self.cla() + try: + self.cla(clear_axis=False) # new xaxis and yaxis are already cleared + except TypeError: + self.cla() # For Axes subclasses lacking clear_axis argument. + # funcs used to format x and y - fall back on major formatters self.fmt_xdata = None self.fmt_ydata = None @@ -607,11 +601,11 @@ def get_window_extent(self, *args, **kwargs): def _init_axis(self): "move this out of __init__ because non-separable axes don't use it" self.xaxis = maxis.XAxis(self) - self.spines['bottom'].register_axis(self.xaxis) - self.spines['top'].register_axis(self.xaxis) + self.spines['bottom'].register_axis(self.xaxis, clear_axis=False) + self.spines['top'].register_axis(self.xaxis, clear_axis=False) self.yaxis = maxis.YAxis(self) - self.spines['left'].register_axis(self.yaxis) - self.spines['right'].register_axis(self.yaxis) + self.spines['left'].register_axis(self.yaxis, clear_axis=False) + self.spines['right'].register_axis(self.yaxis, clear_axis=False) self._update_transScale() def set_figure(self, fig): @@ -634,8 +628,7 @@ def set_figure(self, fig): def _set_lim_and_transforms(self): """ - set the *dataLim* and *viewLim* - :class:`~matplotlib.transforms.Bbox` attributes and the + set the *_xaxis_transform*, *_yaxis_transform*, *transScale*, *transData*, *transLimits* and *transAxes* transformations. @@ -952,7 +945,7 @@ def _gen_axes_spines(self, locations=None, offset=0.0, units='inches'): ('bottom', mspines.Spine.linear_spine(self, 'bottom')), ('top', mspines.Spine.linear_spine(self, 'top'))]) - def cla(self): + def cla(self, clear_axis=True): """Clear the current axes.""" # Note: this is called by Axes.__init__() @@ -965,51 +958,46 @@ def cla(self): xaxis_visible = self.xaxis.get_visible() yaxis_visible = self.yaxis.get_visible() - self.xaxis.cla() - self.yaxis.cla() + # The axis cla() sets the scale and default locators and + # formatters. It needs to know if the axis is shared + # so that it can preserve the shared scale. + shared_x = self._sharex.xaxis if self._sharex else None + shared_y = self._sharey.yaxis if self._sharey else None + + if clear_axis: + self.xaxis.cla(shared_x) + self.yaxis.cla(shared_y) # + for name, spine in six.iteritems(self.spines): - spine.cla() + spine.cla(clear_axis=False) # Clears only the position. self.ignore_existing_data_limits = True self.callbacks = cbook.CallbackRegistry() - if self._sharex is not None: - # major and minor are class instances with + if shared_x is not None: + # major and minor are axis.Ticker class instances with # locator and formatter attributes - self.xaxis.major = self._sharex.xaxis.major - self.xaxis.minor = self._sharex.xaxis.minor + self.xaxis.major = shared_x.major + self.xaxis.minor = shared_x.minor x0, x1 = self._sharex.get_xlim() self.set_xlim(x0, x1, emit=False, auto=None) - self.xaxis._scale = mscale.scale_factory( - self._sharex.xaxis.get_scale(), self.xaxis) else: - self.xaxis._set_scale('linear') try: self.set_xlim(0, 1) except TypeError: pass - if self._sharey is not None: - self.yaxis.major = self._sharey.yaxis.major - self.yaxis.minor = self._sharey.yaxis.minor + if shared_y is not None: + self.yaxis.major = shared_y.major + self.yaxis.minor = shared_y.minor y0, y1 = self._sharey.get_ylim() self.set_ylim(y0, y1, emit=False, auto=None) - self.yaxis._scale = mscale.scale_factory( - self._sharey.yaxis.get_scale(), self.yaxis) else: - self.yaxis._set_scale('linear') try: self.set_ylim(0, 1) except TypeError: pass - # update the minor locator for x and y axis based on rcParams - if (rcParams['xtick.minor.visible']): - self.xaxis.set_minor_locator(mticker.AutoMinorLocator()) - - if (rcParams['ytick.minor.visible']): - self.yaxis.set_minor_locator(mticker.AutoMinorLocator()) - self._autoscaleXon = True self._autoscaleYon = True self._xmargin = rcParams['axes.xmargin'] @@ -1093,6 +1081,14 @@ def cla(self): self.yaxis.set_visible(yaxis_visible) self.patch.set_visible(patch_visible) + # It is not clear to me (EF) why this reset is needed here, but + # it does seem to be needed somewhere in this vicinity. Otherwise, + # setting tick rotation via set_params doesn't work until the + # first draw has occurred. + self.xaxis.reset_ticks() + self.yaxis.reset_ticks() + + self.stale = True @cbook.deprecated("2.1", alternative="Axes.patch") @@ -1224,7 +1220,7 @@ def hold(self, b=None): def get_aspect(self): return self._aspect - def set_aspect(self, aspect, adjustable=None, anchor=None): + def set_aspect(self, aspect, adjustable=None, anchor=None, share=False): """ *aspect* @@ -1245,12 +1241,9 @@ def set_aspect(self, aspect, adjustable=None, anchor=None): ============ ===================================== 'box' change physical size of axes 'datalim' change xlim or ylim - 'box-forced' same as 'box', but axes can be shared ============ ===================================== - 'box' does not allow axes sharing, as this can cause - unintended side effect. For cases when sharing axes is - fine, use 'box-forced'. + When both axes are shared, only 'box' is allowable. *anchor* @@ -1270,8 +1263,17 @@ def set_aspect(self, aspect, adjustable=None, anchor=None): else: self._aspect = float(aspect) # raise ValueError if necessary - if adjustable is not None: - self.set_adjustable(adjustable) + if share and self in self._shared_x_axes: + for ax in self._shared_x_axes.get_siblings(self): + ax._aspect = aspect + if share and self in self._shared_y_axes: + for ax in self._shared_y_axes.get_siblings(self): + ax._aspect = aspect + + if adjustable is None: + adjustable = self._adjustable + self.set_adjustable(adjustable, share=share) # Always call this to handle sharing. + if anchor is not None: self.set_anchor(anchor) self.stale = True @@ -1279,15 +1281,22 @@ def set_aspect(self, aspect, adjustable=None, anchor=None): def get_adjustable(self): return self._adjustable - def set_adjustable(self, adjustable): + def set_adjustable(self, adjustable, share=False): """ - ACCEPTS: [ 'box' | 'datalim' | 'box-forced'] + ACCEPTS: [ 'box' | 'datalim'] """ + # FIXME: add box-forced deprecation if adjustable in ('box', 'datalim', 'box-forced'): - if self in self._shared_x_axes or self in self._shared_y_axes: - if adjustable == 'box': + if self in self._shared_x_axes and self in self._shared_y_axes: + if adjustable == 'datalim': raise ValueError( - 'adjustable must be "datalim" for shared axes') + 'adjustable must be "box" when both axes are shared') + if share and self in self._shared_x_axes: + for ax in self._shared_x_axes.get_siblings(self): + ax._adjustable = adjustable + if share and self in self._shared_y_axes: + for ax in self._shared_y_axes.get_siblings(self): + ax._adjustable = adjustable self._adjustable = adjustable else: raise ValueError('argument must be "box", or "datalim"') @@ -1387,14 +1396,6 @@ def apply_aspect(self, position=None): else: A = aspect - # Ensure at drawing time that any Axes involved in axis-sharing - # does not have its position changed. - if self in self._shared_x_axes or self in self._shared_y_axes: - if self._adjustable == 'box': - self._adjustable = 'datalim' - warnings.warn( - 'shared axes: "adjustable" is being changed to "datalim"') - figW, figH = self.get_figure().get_size_inches() fig_aspect = figH / figW if self._adjustable in ['box', 'box-forced']: @@ -1452,15 +1453,15 @@ def apply_aspect(self, position=None): xm = 0 ym = 0 - changex = (self in self._shared_y_axes and - self not in self._shared_x_axes) - changey = (self in self._shared_x_axes and - self not in self._shared_y_axes) - if changex and changey: - warnings.warn("adjustable='datalim' cannot work with shared " - "x and y axes") - return - if changex: + shared_x = self in self._shared_x_axes + shared_y = self in self._shared_y_axes + # Not sure whether we need this check: + if shared_x and shared_y: + raise RuntimeError("adjustable='datalim' is not allowed when both" + " axes are shared.") + + # If y is shared, then we are only allowed to change x, etc. + if shared_y: adjust_y = False else: if xmarg > xm and ymarg > ym: @@ -1468,7 +1469,8 @@ def apply_aspect(self, position=None): (Xmarg < 0 and y_expander > 0)) else: adjy = y_expander > 0 - adjust_y = changey or adjy # (Ymarg > xmarg) + adjust_y = shared_x or adjy # (Ymarg > xmarg) + if adjust_y: yc = 0.5 * (ymin + ymax) y0 = yc - Ysize / 2.0 @@ -3977,9 +3979,9 @@ def twiny(self): return ax2 def get_shared_x_axes(self): - 'Return a copy of the shared axes Grouper object for x axes' + 'Return a reference to the shared axes Grouper object for x axes' return self._shared_x_axes def get_shared_y_axes(self): - 'Return a copy of the shared axes Grouper object for y axes' + 'Return a reference to the shared axes Grouper object for y axes' return self._shared_y_axes diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 870c5e8f6f72..15ffd47626f1 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -82,6 +82,10 @@ def __init__(self, axes, loc, label, label2On=False, major=True, labelrotation=0, + grid_color=None, + grid_linestyle=None, + grid_linewidth=None, + grid_alpha=None, ): """ bbox is the Bound2D bounding box in display coords of the Axes @@ -149,6 +153,15 @@ def __init__(self, axes, loc, label, zorder = mlines.Line2D.zorder self._zorder = zorder + self._grid_color = (rcParams['grid.color'] + if grid_color is None else grid_color) + self._grid_linestyle = (rcParams['grid.linestyle'] + if grid_linestyle is None else grid_linestyle) + self._grid_linewidth = (rcParams['grid.linewidth'] + if grid_linewidth is None else grid_linewidth) + self._grid_alpha = (rcParams['grid.alpha'] + if grid_alpha is None else grid_alpha) + self.apply_tickdir(tickdir) self.tick1line = self._get_tick1line() @@ -344,6 +357,15 @@ def _apply_params(self, **kw): v = getattr(self.label1, 'get_' + k)() setattr(self, '_label' + k, v) + grid_list = [k for k in six.iteritems(kw) + if k[0] in ['grid_color', 'grid_linestyle', + 'grid_linewidth', 'grid_alpha']] + if grid_list: + grid_kw = {k[5:]: v for k, v in grid_list} + self.gridline.set(**grid_kw) + for k, v in six.iteritems(grid_kw): + setattr(self, '_grid_' + k, v) + def update_position(self, loc): 'Set the location of tick in data coords with scalar *loc*' raise NotImplementedError('Derived must override') @@ -445,10 +467,10 @@ def _get_gridline(self): 'Get the default line2D instance' # x in data coords, y in axes coords l = mlines.Line2D(xdata=(0.0, 0.0), ydata=(0, 1.0), - color=rcParams['grid.color'], - linestyle=rcParams['grid.linestyle'], - linewidth=rcParams['grid.linewidth'], - alpha=rcParams['grid.alpha'], + color=self._grid_color, + linestyle=self._grid_linestyle, + linewidth=self._grid_linewidth, + alpha=self._grid_alpha, markersize=0) l.set_transform(self.axes.get_xaxis_transform(which='grid')) l.get_path()._interpolation_steps = GRIDLINE_INTERPOLATION_STEPS @@ -568,10 +590,10 @@ def _get_gridline(self): 'Get the default line2D instance' # x in axes coords, y in data coords l = mlines.Line2D(xdata=(0, 1), ydata=(0, 0), - color=rcParams['grid.color'], - linestyle=rcParams['grid.linestyle'], - linewidth=rcParams['grid.linewidth'], - alpha=rcParams['grid.alpha'], + color=self._grid_color, + linestyle=self._grid_linestyle, + linewidth=self._grid_linewidth, + alpha=self._grid_alpha, markersize=0) l.set_transform(self.axes.get_yaxis_transform(which='grid')) @@ -626,13 +648,6 @@ def __init__(self, axes, pickradius=15): artist.Artist.__init__(self) self.set_figure(axes.figure) - # Keep track of setting to the default value, this allows use to know - # if any of the following values is explicitly set by the user, so as - # to not overwrite their settings with any of our 'auto' settings. - self.isDefault_majloc = True - self.isDefault_minloc = True - self.isDefault_majfmt = True - self.isDefault_minfmt = True self.isDefault_label = True self.axes = axes @@ -656,7 +671,6 @@ def __init__(self, axes, pickradius=15): self._minor_tick_kw = dict() self.cla() - self._set_scale('linear') def set_label_coords(self, x, y, transform=None): """ @@ -719,24 +733,17 @@ def get_children(self): children.extend(minorticks) return children - def cla(self): + def cla(self, shared=None): 'clear the current axis' - self.set_major_locator(mticker.AutoLocator()) - self.set_major_formatter(mticker.ScalarFormatter()) - self.set_minor_locator(mticker.NullLocator()) - self.set_minor_formatter(mticker.NullFormatter()) - self.set_label_text('') - self._set_artist_props(self.label) + self.label.set_text('') # self.set_label_text would change isDefault_ + self._set_artist_props(self.label) # sets figure; needed here? - # Keep track of setting to the default value, this allows use to know - # if any of the following values is explicitly set by the user, so as - # to not overwrite their settings with any of our 'auto' settings. - self.isDefault_majloc = True - self.isDefault_minloc = True - self.isDefault_majfmt = True - self.isDefault_minfmt = True - self.isDefault_label = True + if shared is None: + self._set_scale('linear') + else: + name = shared.get_scale() + self._scale = mscale.scale_factory(name, self) # Clear the callback registry for this axis, or it may "leak" self.callbacks = cbook.CallbackRegistry() @@ -747,9 +754,6 @@ def cla(self): self._gridOnMinor = (rcParams['axes.grid'] and rcParams['axes.grid.which'] in ('both', 'minor')) - self.label.set_text('') - self._set_artist_props(self.label) - self.reset_ticks() self.converter = None @@ -769,6 +773,11 @@ def reset_ticks(self): self._lastNumMajorTicks = 1 self._lastNumMinorTicks = 1 + try: + self.set_clip_path(self.axes.patch) + except AttributeError: + pass + def set_tick_params(self, which='major', reset=False, **kw): """ Set appearance parameters for ticks and ticklabels. @@ -786,8 +795,10 @@ def set_tick_params(self, which='major', reset=False, **kw): if reset: d.clear() d.update(kwtrans) + if reset: self.reset_ticks() + # Is this "else" correct? Shouldn't kwargs be applied after a reset? else: if which == 'major' or which == 'both': for tick in self.majorTicks: @@ -809,7 +820,9 @@ def _translate_tick_kw(kw, to_init_kw=True): kwkeys1 = ['length', 'direction', 'left', 'bottom', 'right', 'top', 'labelleft', 'labelbottom', 'labelright', 'labeltop', 'rotation'] - kwkeys = kwkeys0 + kwkeys1 + kwkeys2 = ['grid_color', 'grid_linestyle', 'grid_linewidth', + 'grid_alpha'] + kwkeys = kwkeys0 + kwkeys1 + kwkeys2 kwtrans = dict() if to_init_kw: if 'length' in kw: @@ -951,7 +964,7 @@ def _update_ticks(self, renderer): """ interval = self.get_view_interval() - tick_tups = list(self.iter_ticks()) + tick_tups = list(self.iter_ticks()) # iter_ticks calls the locator if self._smart_bounds and tick_tups: # handle inverted limits view_low, view_high = sorted(interval) @@ -1376,30 +1389,21 @@ def grid(self, b=None, which='major', **kwargs): if len(kwargs): b = True which = which.lower() + gridkw = {'grid_' + item[0]: item[1] for item in kwargs.items()} if which in ['minor', 'both']: if b is None: self._gridOnMinor = not self._gridOnMinor else: self._gridOnMinor = b - for tick in self.minorTicks: # don't use get_ticks here! - if tick is None: - continue - tick.gridOn = self._gridOnMinor - if len(kwargs): - tick.gridline.update(kwargs) - self._minor_tick_kw['gridOn'] = self._gridOnMinor + self.set_tick_params(which='minor', gridOn=self._gridOnMinor, + **gridkw) if which in ['major', 'both']: if b is None: self._gridOnMajor = not self._gridOnMajor else: self._gridOnMajor = b - for tick in self.majorTicks: # don't use get_ticks here! - if tick is None: - continue - tick.gridOn = self._gridOnMajor - if len(kwargs): - tick.gridline.update(kwargs) - self._major_tick_kw['gridOn'] = self._gridOnMajor + self.set_tick_params(which='major', gridOn=self._gridOnMajor, + **gridkw) self.stale = True def update_units(self, data): @@ -1429,11 +1433,11 @@ def _update_axisinfo(self): check the axis converter for the stored units to see if the axis info needs to be updated """ - if self.converter is None: return info = self.converter.axisinfo(self.units, self) + if info is None: return if info.majloc is not None and \ diff --git a/lib/matplotlib/scale.py b/lib/matplotlib/scale.py index 29a38b6663c2..b4971d454ad2 100644 --- a/lib/matplotlib/scale.py +++ b/lib/matplotlib/scale.py @@ -10,9 +10,10 @@ from matplotlib.ticker import (NullFormatter, ScalarFormatter, LogFormatterSciNotation, LogitFormatter) from matplotlib.ticker import (NullLocator, LogLocator, AutoLocator, + AutoMinorLocator, SymmetricalLogLocator, LogitLocator) from matplotlib.transforms import Transform, IdentityTransform -from matplotlib import docstring +from matplotlib import docstring, rcParams class ScaleBase(object): @@ -73,8 +74,12 @@ def set_default_locators_and_formatters(self, axis): """ axis.set_major_locator(AutoLocator()) axis.set_major_formatter(ScalarFormatter()) - axis.set_minor_locator(NullLocator()) axis.set_minor_formatter(NullFormatter()) + # update the minor locator for x and y axis based on rcParams + if (rcParams['xtick.minor.visible']): + axis.set_minor_locator(AutoMinorLocator()) + else: + axis.set_minor_locator(NullLocator()) def get_transform(self): """ diff --git a/lib/matplotlib/spines.py b/lib/matplotlib/spines.py index c6b04fe43dba..de5c294ad856 100644 --- a/lib/matplotlib/spines.py +++ b/lib/matplotlib/spines.py @@ -151,7 +151,7 @@ def _ensure_position_is_set(self): self._position = ('outward', 0.0) # in points self.set_position(self._position) - def register_axis(self, axis): + def register_axis(self, axis, clear_axis=True): """register an axis An axis should be registered with its corresponding spine from @@ -159,14 +159,14 @@ def register_axis(self, axis): properties when needed. """ self.axis = axis - if self.axis is not None: + if clear_axis and self.axis is not None: self.axis.cla() self.stale = True - def cla(self): + def cla(self, clear_axis=True): """Clear the current spine""" self._position = None # clear position - if self.axis is not None: + if clear_axis and self.axis is not None: self.axis.cla() def is_frame_like(self): diff --git a/lib/matplotlib/tests/baseline_images/test_skew/skew_rects.pdf b/lib/matplotlib/tests/baseline_images/test_skew/skew_rects.pdf index 209842345b463aa2c0030d50488ac46e4b7a266a..c16fc9c2d916904dc79b2fbd5743088668183f08 100644 GIT binary patch literal 7923 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
_m1wt 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 diff --git a/lib/matplotlib/tests/baseline_images/test_skew/skew_rects.svg b/lib/matplotlib/tests/baseline_images/test_skew/skew_rects.svg index 668efde6a8ad..ff18e2b4df0b 100644 --- a/lib/matplotlib/tests/baseline_images/test_skew/skew_rects.svg +++ b/lib/matplotlib/tests/baseline_images/test_skew/skew_rects.svg @@ -2,7 +2,7 @@ - + - - - - - - - @@ -60,188 +60,188 @@ L 230.4 86.4 +" id="m368fc901b1" style="stroke:#000000;stroke-width:0.5;"/> - + +" id="mc63e59a608" style="stroke:#000000;stroke-width:0.5;"/> - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + - + + + + - + - + - + - + - - - + - - - - + - - - - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -249,209 +249,209 @@ L -4 0 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -459,209 +459,209 @@ L 460.8 86.4 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -669,209 +669,209 @@ L 691.2 86.4 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -879,209 +879,209 @@ L 921.6 86.4 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1089,209 +1089,209 @@ L 1152 86.4 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1299,209 +1299,209 @@ L 230.4 247.282759 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1509,209 +1509,209 @@ L 460.8 247.282759 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1719,209 +1719,209 @@ L 691.2 247.282759 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1929,209 +1929,209 @@ L 921.6 247.282759 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2139,209 +2139,209 @@ L 1152 247.282759 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2349,209 +2349,209 @@ L 230.4 408.165517 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2559,209 +2559,209 @@ L 460.8 408.165517 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2769,209 +2769,209 @@ L 691.2 408.165517 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2979,209 +2979,209 @@ L 921.6 408.165517 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -3189,209 +3189,209 @@ L 1152 408.165517 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -3399,209 +3399,209 @@ L 230.4 569.048276 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -3609,209 +3609,209 @@ L 460.8 569.048276 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -3819,209 +3819,209 @@ L 691.2 569.048276 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -4029,209 +4029,209 @@ L 921.6 569.048276 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -4239,209 +4239,209 @@ L 1152 569.048276 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -4449,209 +4449,209 @@ L 230.4 729.931034 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -4659,209 +4659,209 @@ L 460.8 729.931034 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -4869,209 +4869,209 @@ L 691.2 729.931034 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -5079,209 +5079,209 @@ L 921.6 729.931034 - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + - + - + - + - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -5289,80 +5289,80 @@ L 1152 729.931034 - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index f1cc67fde7a4..87c97956aaed 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -4220,6 +4220,48 @@ def test_empty_shared_subplots(): assert y1 >= 6 +def test_shared_with_aspect(): + # allow sharing one axis + for adjustable in ['box', 'datalim']: + fig, axes = plt.subplots(nrows=2, sharex=True) + axes[0].set_aspect(2, adjustable=adjustable, share=True) + assert axes[1].get_aspect() == 2 + assert axes[1].get_adjustable() == adjustable + + fig, axes = plt.subplots(nrows=2, sharex=True) + axes[0].set_aspect(2, adjustable=adjustable) + assert axes[1].get_aspect() == 'auto' + + # Share 2 axes only with 'box': + fig, axes = plt.subplots(nrows=2, sharex=True, sharey=True) + axes[0].set_aspect(2, share=True) + axes[0].plot([1, 2], [3, 4]) + axes[1].plot([3, 4], [1, 2]) + plt.draw() # Trigger apply_aspect(). + assert axes[0].get_xlim() == axes[1].get_xlim() + assert axes[0].get_ylim() == axes[1].get_ylim() + with pytest.raises(ValueError): + axes[0].set_aspect(1, adjustable='datalim', share=True) + + # Different aspect ratios: + for adjustable in ['box', 'datalim']: + fig, axes = plt.subplots(nrows=2, sharey=True) + axes[0].set_aspect(2, adjustable=adjustable) + axes[1].set_aspect(0.5, adjustable=adjustable) + axes[0].plot([1, 2], [3, 4]) + axes[1].plot([3, 4], [1, 2]) + plt.draw() # Trigger apply_aspect(). + assert axes[0].get_xlim() != axes[1].get_xlim() + assert axes[0].get_ylim() == axes[1].get_ylim() + fig_aspect = fig.bbox_inches.height / fig.bbox_inches.width + for ax in axes: + p = ax.get_position() + box_aspect = p.height / p.width + lim_aspect = ax.viewLim.height / ax.viewLim.width + expected = fig_aspect * box_aspect / lim_aspect + assert round(expected, 4) == round(ax.get_aspect(), 4) + + def test_relim_visible_only(): x1 = (0., 10.) y1 = (0., 10.) diff --git a/lib/matplotlib/tests/test_skew.py b/lib/matplotlib/tests/test_skew.py index 79cb75c2c273..a80d3cdaf002 100644 --- a/lib/matplotlib/tests/test_skew.py +++ b/lib/matplotlib/tests/test_skew.py @@ -189,16 +189,16 @@ def test_set_line_coll_dash_image(): @image_comparison(baseline_images=['skew_rects'], remove_text=True) -def test_skew_rectange(): +def test_skew_rectangle(): - fix, axes = plt.subplots(5, 5, sharex=True, sharey=True, figsize=(16, 12)) + fix, axes = plt.subplots(5, 5, sharex=True, sharey=True, figsize=(8, 8)) axes = axes.flat rotations = list(itertools.product([-3, -1, 0, 1, 3], repeat=2)) - axes[0].set_xlim([-4, 4]) - axes[0].set_ylim([-4, 4]) - axes[0].set_aspect('equal') + axes[0].set_xlim([-3, 3]) + axes[0].set_ylim([-3, 3]) + axes[0].set_aspect('equal', share=True) for ax, (xrots, yrots) in zip(axes, rotations): xdeg, ydeg = 45 * xrots, 45 * yrots @@ -209,4 +209,4 @@ def test_skew_rectange(): transform=t + ax.transData, alpha=0.5, facecolor='coral')) - plt.subplots_adjust(wspace=0, left=0, right=1, bottom=0) + plt.subplots_adjust(wspace=0, left=0.01, right=0.99, bottom=0.01, top=0.99) From 2de8089cd98c16409e0a3ef877b2fed6fdeeb659 Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Tue, 13 Jun 2017 08:20:26 -1000 Subject: [PATCH 2/7] Fix PEP8 errors --- lib/matplotlib/axes/_base.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index ac89374f27c8..39f1da6ad522 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -528,7 +528,7 @@ def __init__(self, fig, rect, self._connected = {} # a dict from events to (id, func) try: - self.cla(clear_axis=False) # new xaxis and yaxis are already cleared + self.cla(clear_axis=False) # new xaxis, yaxis are already cleared except TypeError: self.cla() # For Axes subclasses lacking clear_axis argument. @@ -1088,7 +1088,6 @@ def cla(self, clear_axis=True): self.xaxis.reset_ticks() self.yaxis.reset_ticks() - self.stale = True @cbook.deprecated("2.1", alternative="Axes.patch") @@ -1272,7 +1271,7 @@ def set_aspect(self, aspect, adjustable=None, anchor=None, share=False): if adjustable is None: adjustable = self._adjustable - self.set_adjustable(adjustable, share=share) # Always call this to handle sharing. + self.set_adjustable(adjustable, share=share) # Handle sharing. if anchor is not None: self.set_anchor(anchor) From 748c759f6f8963aea98568631d3645a8ac0d19f3 Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Thu, 15 Jun 2017 16:49:33 -0400 Subject: [PATCH 3/7] Minor fixups from qlogic review --- lib/matplotlib/axes/_base.py | 2 +- lib/matplotlib/axis.py | 4 +--- lib/matplotlib/scale.py | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 39f1da6ad522..b0f0484430a6 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -966,7 +966,7 @@ def cla(self, clear_axis=True): if clear_axis: self.xaxis.cla(shared_x) - self.yaxis.cla(shared_y) # + self.yaxis.cla(shared_y) for name, spine in six.iteritems(self.spines): spine.cla(clear_axis=False) # Clears only the position. diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 15ffd47626f1..70db796c287a 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -160,7 +160,7 @@ def __init__(self, axes, loc, label, self._grid_linewidth = (rcParams['grid.linewidth'] if grid_linewidth is None else grid_linewidth) self._grid_alpha = (rcParams['grid.alpha'] - if grid_alpha is None else grid_alpha) + if grid_alpha is None else grid_alpha) self.apply_tickdir(tickdir) @@ -737,7 +737,6 @@ def cla(self, shared=None): 'clear the current axis' self.label.set_text('') # self.set_label_text would change isDefault_ - self._set_artist_props(self.label) # sets figure; needed here? if shared is None: self._set_scale('linear') @@ -798,7 +797,6 @@ def set_tick_params(self, which='major', reset=False, **kw): if reset: self.reset_ticks() - # Is this "else" correct? Shouldn't kwargs be applied after a reset? else: if which == 'major' or which == 'both': for tick in self.majorTicks: diff --git a/lib/matplotlib/scale.py b/lib/matplotlib/scale.py index b4971d454ad2..e1df53b97a04 100644 --- a/lib/matplotlib/scale.py +++ b/lib/matplotlib/scale.py @@ -76,7 +76,7 @@ def set_default_locators_and_formatters(self, axis): axis.set_major_formatter(ScalarFormatter()) axis.set_minor_formatter(NullFormatter()) # update the minor locator for x and y axis based on rcParams - if (rcParams['xtick.minor.visible']): + if rcParams['xtick.minor.visible']: axis.set_minor_locator(AutoMinorLocator()) else: axis.set_minor_locator(NullLocator()) From bff7e12f7e3b9f8feafc590bfd155a982889ca2f Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Thu, 15 Jun 2017 17:50:28 -0400 Subject: [PATCH 4/7] Single extra space removed to placate PEP 8. --- lib/matplotlib/tests/test_axes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 87c97956aaed..0eb0271fe5f9 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -4259,7 +4259,7 @@ def test_shared_with_aspect(): box_aspect = p.height / p.width lim_aspect = ax.viewLim.height / ax.viewLim.width expected = fig_aspect * box_aspect / lim_aspect - assert round(expected, 4) == round(ax.get_aspect(), 4) + assert round(expected, 4) == round(ax.get_aspect(), 4) def test_relim_visible_only(): From f493ac3db8d8aead809048e4527528b90c4372aa Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Fri, 16 Jun 2017 13:12:04 -0400 Subject: [PATCH 5/7] 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. --- lib/matplotlib/axis.py | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 70db796c287a..67d75a31770a 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -24,6 +24,13 @@ GRIDLINE_INTERPOLATION_STEPS = 180 +# This list is being used for compatibility with Axes.grid, which +# allows all Line2D kwargs. +_line_AI = artist.ArtistInspector(mlines.Line2D) +_line_param_names = _line_AI.get_setters() +_line_param_aliases = [list(d.keys())[0] for d in _line_AI.aliasd.values()] +_gridline_param_names = ['grid_' + name + for name in _line_param_names + _line_param_aliases] class Tick(artist.Artist): """ @@ -86,6 +93,7 @@ def __init__(self, axes, loc, label, grid_linestyle=None, grid_linewidth=None, grid_alpha=None, + **kw # Other Line2D kwargs applied to gridlines. ): """ bbox is the Bound2D bounding box in display coords of the Axes @@ -162,6 +170,8 @@ def __init__(self, axes, loc, label, self._grid_alpha = (rcParams['grid.alpha'] if grid_alpha is None else grid_alpha) + self._grid_kw = {k[5:]:v for k, v in kw.items()} + self.apply_tickdir(tickdir) self.tick1line = self._get_tick1line() @@ -358,8 +368,7 @@ def _apply_params(self, **kw): setattr(self, '_label' + k, v) grid_list = [k for k in six.iteritems(kw) - if k[0] in ['grid_color', 'grid_linestyle', - 'grid_linewidth', 'grid_alpha']] + if k[0] in _gridline_param_names] if grid_list: grid_kw = {k[5:]: v for k, v in grid_list} self.gridline.set(**grid_kw) @@ -471,7 +480,8 @@ def _get_gridline(self): linestyle=self._grid_linestyle, linewidth=self._grid_linewidth, alpha=self._grid_alpha, - markersize=0) + markersize=0, + **self._grid_kw) l.set_transform(self.axes.get_xaxis_transform(which='grid')) l.get_path()._interpolation_steps = GRIDLINE_INTERPOLATION_STEPS self._set_artist_props(l) @@ -594,8 +604,8 @@ def _get_gridline(self): linestyle=self._grid_linestyle, linewidth=self._grid_linewidth, alpha=self._grid_alpha, - markersize=0) - + markersize=0, + **self._grid_kw) l.set_transform(self.axes.get_yaxis_transform(which='grid')) l.get_path()._interpolation_steps = GRIDLINE_INTERPOLATION_STEPS self._set_artist_props(l) @@ -761,9 +771,11 @@ def cla(self, shared=None): self.stale = True def reset_ticks(self): - # build a few default ticks; grow as necessary later; only - # define 1 so properties set on ticks will be copied as they - # grow + """ + Re-initialize the major and minor Tick lists. + + Each list starts with a single fresh Tick. + """ del self.majorTicks[:] del self.minorTicks[:] @@ -818,8 +830,7 @@ def _translate_tick_kw(kw, to_init_kw=True): kwkeys1 = ['length', 'direction', 'left', 'bottom', 'right', 'top', 'labelleft', 'labelbottom', 'labelright', 'labeltop', 'rotation'] - kwkeys2 = ['grid_color', 'grid_linestyle', 'grid_linewidth', - 'grid_alpha'] + kwkeys2 = _gridline_param_names kwkeys = kwkeys0 + kwkeys1 + kwkeys2 kwtrans = dict() if to_init_kw: From d575d60170be77d372a18a0343910b2f5f56cb10 Mon Sep 17 00:00:00 2001 From: Eric Firing Date: Fri, 16 Jun 2017 13:33:39 -0400 Subject: [PATCH 6/7] PEP 8 again --- lib/matplotlib/axis.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 67d75a31770a..91930dd9611a 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -28,10 +28,11 @@ # allows all Line2D kwargs. _line_AI = artist.ArtistInspector(mlines.Line2D) _line_param_names = _line_AI.get_setters() -_line_param_aliases = [list(d.keys())[0] for d in _line_AI.aliasd.values()] +_line_param_aliases = [list(d.keys())[0] for d in _line_AI.aliasd.values()] _gridline_param_names = ['grid_' + name for name in _line_param_names + _line_param_aliases] + class Tick(artist.Artist): """ Abstract base class for the axis ticks, grid lines and labels @@ -170,7 +171,7 @@ def __init__(self, axes, loc, label, self._grid_alpha = (rcParams['grid.alpha'] if grid_alpha is None else grid_alpha) - self._grid_kw = {k[5:]:v for k, v in kw.items()} + self._grid_kw = {k[5:]: v for k, v in kw.items()} self.apply_tickdir(tickdir) From 7dba6868b10a722b37f7ba0d1fc119d9b8a233de Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sun, 2 Jul 2017 18:49:46 -0400 Subject: [PATCH 7/7] API: re-allow 'datalim' as a valid adjustable with shared axes This is to allow twinx and twiny to work as expected. --- lib/matplotlib/axes/_base.py | 9 ++++----- lib/matplotlib/tests/test_axes.py | 13 +++++++++++-- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index b0f0484430a6..674f56639e5a 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -438,7 +438,7 @@ def __init__(self, fig, rect, ================ ========================================= Keyword Description ================ ========================================= - *adjustable* [ 'box' | 'datalim' | 'box-forced'] + *adjustable* [ 'box' | 'datalim' ] *alpha* float: the alpha transparency (can be None) *anchor* [ 'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', 'NW', 'W' ] @@ -1286,10 +1286,6 @@ def set_adjustable(self, adjustable, share=False): """ # FIXME: add box-forced deprecation if adjustable in ('box', 'datalim', 'box-forced'): - if self in self._shared_x_axes and self in self._shared_y_axes: - if adjustable == 'datalim': - raise ValueError( - 'adjustable must be "box" when both axes are shared') if share and self in self._shared_x_axes: for ax in self._shared_x_axes.get_siblings(self): ax._adjustable = adjustable @@ -3916,6 +3912,9 @@ def _make_twin_axes(self, *kl, **kwargs): make a twinx axes of self. This is used for twinx and twiny. """ ax2 = self.figure.add_axes(self.get_position(True), *kl, **kwargs) + # do not touch every thing shared, just this and it's twin. + self.set_adjustable('datalim') + ax2.set_adjustable('datalim') return ax2 def twinx(self): diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 0eb0271fe5f9..14ef9f04fdbe 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -4240,8 +4240,6 @@ def test_shared_with_aspect(): plt.draw() # Trigger apply_aspect(). assert axes[0].get_xlim() == axes[1].get_xlim() assert axes[0].get_ylim() == axes[1].get_ylim() - with pytest.raises(ValueError): - axes[0].set_aspect(1, adjustable='datalim', share=True) # Different aspect ratios: for adjustable in ['box', 'datalim']: @@ -4262,6 +4260,17 @@ def test_shared_with_aspect(): assert round(expected, 4) == round(ax.get_aspect(), 4) +@pytest.mark.parametrize('twin', ('x', 'y')) +def test_twin_with_aspect(twin): + fig, ax = plt.subplots() + # test twinx or twiny + ax_twin = getattr(ax, 'twin{}'.format(twin))() + ax.set_aspect(5) + ax_twin.set_aspect(2) + assert_array_equal(ax.bbox.extents, + ax_twin.bbox.extents) + + def test_relim_visible_only(): x1 = (0., 10.) y1 = (0., 10.) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy