diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index b18c567f79cb..97c79df79720 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1569,8 +1569,8 @@ def set_ticks(self, ticks, minor=False): def _update_label_position(self, bboxes, bboxes2): """ - Update the label position based on the sequence of bounding - boxes of all the ticklabels + Update the label position based on the the bounding box enclosing + all the ticklabels and axis spine """ raise NotImplementedError('Derived must override') @@ -1725,28 +1725,38 @@ def set_label_position(self, position): def _update_label_position(self, bboxes, bboxes2): """ - Update the label position based on the sequence of bounding - boxes of all the ticklabels + Update the label position based on the the bounding box enclosing + all the ticklabels and axis spine """ if not self._autolabelpos: return x, y = self.label.get_position() if self.label_position == 'bottom': - if not len(bboxes): - bottom = self.axes.bbox.ymin - else: - bbox = mtransforms.Bbox.union(bboxes) - bottom = bbox.y0 + try: + spine = self.axes.spines['bottom'] + spinebbox = spine.get_transform().transform_path( + spine.get_path()).get_extents() + except KeyError: + # use axes if spine doesn't exist + spinebbox = self.axes.bbox + bbox = mtransforms.Bbox.union(bboxes + [spinebbox]) + bottom = bbox.y0 + self.label.set_position( (x, bottom - self.labelpad * self.figure.dpi / 72.0) ) else: - if not len(bboxes2): - top = self.axes.bbox.ymax - else: - bbox = mtransforms.Bbox.union(bboxes2) - top = bbox.y1 + try: + spine = self.axes.spines['top'] + spinebbox = spine.get_transform().transform_path( + spine.get_path()).get_extents() + except KeyError: + # use axes if spine doesn't exist + spinebbox = self.axes.bbox + bbox = mtransforms.Bbox.union(bboxes2 + [spinebbox]) + top = bbox.y1 + self.label.set_position( (x, top + self.labelpad * self.figure.dpi / 72.0) ) @@ -2031,29 +2041,37 @@ def set_label_position(self, position): def _update_label_position(self, bboxes, bboxes2): """ - Update the label position based on the sequence of bounding - boxes of all the ticklabels + Update the label position based on the the bounding box enclosing + all the ticklabels and axis spine """ if not self._autolabelpos: return x, y = self.label.get_position() if self.label_position == 'left': - if not len(bboxes): - left = self.axes.bbox.xmin - else: - bbox = mtransforms.Bbox.union(bboxes) - left = bbox.x0 + try: + spine = self.axes.spines['left'] + spinebbox = spine.get_transform().transform_path( + spine.get_path()).get_extents() + except KeyError: + # use axes if spine doesn't exist + spinebbox = self.axes.bbox + bbox = mtransforms.Bbox.union(bboxes + [spinebbox]) + left = bbox.x0 self.label.set_position( (left - self.labelpad * self.figure.dpi / 72.0, y) ) else: - if not len(bboxes2): - right = self.axes.bbox.xmax - else: - bbox = mtransforms.Bbox.union(bboxes2) - right = bbox.x1 + try: + spine = self.axes.spines['right'] + spinebbox = spine.get_transform().transform_path( + spine.get_path()).get_extents() + except KeyError: + # use axes if spine doesn't exist + spinebbox = self.axes.bbox + bbox = mtransforms.Bbox.union(bboxes2 + [spinebbox]) + right = bbox.x1 self.label.set_position( (right + self.labelpad * self.figure.dpi / 72.0, y) @@ -2146,8 +2164,8 @@ def get_ticks_position(self): majt = self.majorTicks[0] mT = self.minorTicks[0] - majorRight = ((not majt.tick1On) and majt.tick2On - and (not majt.label1On) and majt.label2On) + majorRight = ((not majt.tick1On) and majt.tick2On and + (not majt.label1On) and majt.label2On) minorRight = ((not mT.tick1On) and mT.tick2On and (not mT.label1On) and mT.label2On) if majorRight and minorRight: diff --git a/lib/matplotlib/tests/test_coding_standards.py b/lib/matplotlib/tests/test_coding_standards.py index 51559b782170..33a818899df9 100644 --- a/lib/matplotlib/tests/test_coding_standards.py +++ b/lib/matplotlib/tests/test_coding_standards.py @@ -213,7 +213,6 @@ def test_pep8_conformance_installed_files(): 'tests/test_mathtext.py', 'tests/test_rcparams.py', 'tests/test_simplification.py', - 'tests/test_spines.py', 'tests/test_streamplot.py', 'tests/test_subplots.py', 'tests/test_tightlayout.py', diff --git a/lib/matplotlib/tests/test_spines.py b/lib/matplotlib/tests/test_spines.py index bbf149d8bb4b..b628249160ef 100644 --- a/lib/matplotlib/tests/test_spines.py +++ b/lib/matplotlib/tests/test_spines.py @@ -1,45 +1,83 @@ from __future__ import (absolute_import, division, print_function, unicode_literals) +import numpy as np +from nose.tools import assert_true import six -import numpy as np import matplotlib -from matplotlib.testing.decorators import image_comparison import matplotlib.pyplot as plt +import matplotlib.transforms as mtransforms +from matplotlib.testing.decorators import image_comparison, cleanup + @image_comparison(baseline_images=['spines_axes_positions']) def test_spines_axes_positions(): # SF bug 2852168 fig = plt.figure() - x = np.linspace(0,2*np.pi,100) + x = np.linspace(0, 2*np.pi, 100) y = 2*np.sin(x) - ax = fig.add_subplot(1,1,1) + ax = fig.add_subplot(1, 1, 1) ax.set_title('centered spines') - ax.plot(x,y) - ax.spines['right'].set_position(('axes',0.1)) + ax.plot(x, y) + ax.spines['right'].set_position(('axes', 0.1)) ax.yaxis.set_ticks_position('right') - ax.spines['top'].set_position(('axes',0.25)) + ax.spines['top'].set_position(('axes', 0.25)) ax.xaxis.set_ticks_position('top') ax.spines['left'].set_color('none') ax.spines['bottom'].set_color('none') + @image_comparison(baseline_images=['spines_data_positions']) def test_spines_data_positions(): fig = plt.figure() - ax = fig.add_subplot(1,1,1) + ax = fig.add_subplot(1, 1, 1) ax.spines['left'].set_position(('data', -1.5)) ax.spines['top'].set_position(('data', 0.5)) ax.spines['right'].set_position(('data', -0.5)) ax.spines['bottom'].set_position('zero') - ax.set_xlim([-2,2]) - ax.set_ylim([-2,2]) + ax.set_xlim([-2, 2]) + ax.set_ylim([-2, 2]) + @image_comparison(baseline_images=['spines_capstyle']) def test_spines_capstyle(): # issue 2542 plt.rc('axes', linewidth=20) fig = plt.figure() - ax = fig.add_subplot(1,1,1) + ax = fig.add_subplot(1, 1, 1) ax.set_xticks([]) ax.set_yticks([]) + + +@cleanup +def test_label_without_ticks(): + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1) + plt.subplots_adjust(left=0.3, bottom=0.3) + ax.plot(np.arange(10)) + ax.yaxis.set_ticks_position('left') + ax.spines['left'].set_position(('outward', 30)) + ax.spines['right'].set_visible(False) + ax.set_ylabel('y label') + ax.xaxis.set_ticks_position('bottom') + ax.spines['bottom'].set_position(('outward', 30)) + ax.spines['top'].set_visible(False) + ax.set_xlabel('x label') + ax.xaxis.set_ticks([]) + ax.yaxis.set_ticks([]) + plt.draw() + + spine = ax.spines['left'] + spinebbox = spine.get_transform().transform_path( + spine.get_path()).get_extents() + # replace with assert_less if >python2.6 + assert_true(ax.yaxis.label.get_position()[0] < spinebbox.xmin, + "Y-Axis label not left of the spine") + + spine = ax.spines['bottom'] + spinebbox = spine.get_transform().transform_path( + spine.get_path()).get_extents() + # replace with assert_less if >python2.6 + assert_true(ax.xaxis.label.get_position()[1] < spinebbox.ymin, + "X-Axis label not below the spine")