diff --git a/doc/users/whats_new.rst b/doc/users/whats_new.rst index cee2704fa199..281d027539bf 100644 --- a/doc/users/whats_new.rst +++ b/doc/users/whats_new.rst @@ -742,6 +742,13 @@ way as setting `CC` or `CXX` before building. An example follows. export PKG_CONFIG=x86_64-pc-linux-gnu-pkg-config +AxesGrid toolkit +---------------- + +Twins of host axes (see `~mpl_toolkits.axes_grid1.host_subplot()` and its +``twin*`` methods) now have ``remove()`` functionality. Some visibility changes +made by the ``twin*`` methods were modified to faciliate this feature. + .. _whats-new-1-4: new in matplotlib-1.4 diff --git a/lib/mpl_toolkits/axes_grid1/parasite_axes.py b/lib/mpl_toolkits/axes_grid1/parasite_axes.py index 1241c93a0d67..009d5f7e0d5c 100644 --- a/lib/mpl_toolkits/axes_grid1/parasite_axes.py +++ b/lib/mpl_toolkits/axes_grid1/parasite_axes.py @@ -255,6 +255,7 @@ def get_aux_axes(self, tr, viewlim_mode="equal", axes_class=None): # note that ax2.transData == tr + ax1.transData # Anthing you draw in ax2 will match the ticks and grids of ax1. self.parasites.append(ax2) + ax2._remove_method = lambda h: self.parasites.remove(h) return ax2 @@ -326,17 +327,16 @@ def twinx(self, axes_class=None): ax2 = parasite_axes_class(self, sharex=self, frameon=False) self.parasites.append(ax2) - # for normal axes - - self.axis["right"].toggle(all=False) - self.axis["right"].line.set_visible(True) + self.axis["right"].set_visible(False) ax2.axis["right"].set_visible(True) - ax2.axis["left","top", "bottom"].toggle(all=False) - ax2.axis["left","top", "bottom"].line.set_visible(False) + ax2.axis["left", "top", "bottom"].set_visible(False) - ax2.axis["right"].toggle(all=True) - ax2.axis["right"].line.set_visible(False) + def _remove_method(h): + self.parasites.remove(h) + self.axis["right"].set_visible(True) + self.axis["right"].toggle(ticklabels=False, label=False) + ax2._remove_method = _remove_method return ax2 @@ -360,15 +360,16 @@ def twiny(self, axes_class=None): ax2 = parasite_axes_class(self, sharey=self, frameon=False) self.parasites.append(ax2) - self.axis["top"].toggle(all=False) - self.axis["top"].line.set_visible(True) + self.axis["top"].set_visible(False) ax2.axis["top"].set_visible(True) - ax2.axis["left","right", "bottom"].toggle(all=False) - ax2.axis["left","right", "bottom"].line.set_visible(False) + ax2.axis["left", "right", "bottom"].set_visible(False) - ax2.axis["top"].toggle(all=True) - ax2.axis["top"].line.set_visible(False) + def _remove_method(h): + self.parasites.remove(h) + self.axis["top"].set_visible(True) + self.axis["top"].toggle(ticklabels=False, label=False) + ax2._remove_method = _remove_method return ax2 @@ -399,43 +400,18 @@ def twin(self, aux_trans=None, axes_class=None): viewlim_mode="transform", ) self.parasites.append(ax2) + ax2._remove_method = lambda h: self.parasites.remove(h) + self.axis["top", "right"].set_visible(False) - # for normal axes - #self.yaxis.tick_left() - #self.xaxis.tick_bottom() - #ax2.yaxis.tick_right() - #ax2.xaxis.set_visible(True) - #ax2.yaxis.set_visible(True) - - #ax2.yaxis.set_label_position('right') - ##ax2.xaxis.tick_top() - #ax2.xaxis.set_label_position('top') - - - self.axis["top","right"].toggle(all=False) - self.axis["top","right"].line.set_visible(False) - #self.axis["left","bottom"].toggle(label=True) - - ax2.axis["top","right"].set_visible(True) - - ax2.axis["bottom","left"].toggle(all=False) - ax2.axis["bottom","left"].line.set_visible(False) - - ax2.axis["top","right"].toggle(all=True) - ax2.axis["top","right"].line.set_visible(True) - - - # # for axisline axes - # self._axislines["right"].set_visible(False) - # self._axislines["top"].set_visible(False) - # ax2._axislines["left"].set_visible(False) - # ax2._axislines["bottom"].set_visible(False) + ax2.axis["top", "right"].set_visible(True) + ax2.axis["left", "bottom"].set_visible(False) - # ax2._axislines["right"].set_visible(True) - # ax2._axislines["top"].set_visible(True) - # ax2._axislines["right"].major_ticklabels.set_visible(True) - # ax2._axislines["top"].major_ticklabels.set_visible(True) + def _remove_method(h): + self.parasites.remove(h) + self.axis["top", "right"].set_visible(True) + self.axis["top", "right"].toggle(ticklabels=False, label=False) + ax2._remove_method = _remove_method return ax2 diff --git a/lib/mpl_toolkits/tests/baseline_images/test_axes_grid1/twin_axes_empty_and_removed.png b/lib/mpl_toolkits/tests/baseline_images/test_axes_grid1/twin_axes_empty_and_removed.png new file mode 100644 index 000000000000..04be90540bfa Binary files /dev/null and b/lib/mpl_toolkits/tests/baseline_images/test_axes_grid1/twin_axes_empty_and_removed.png differ diff --git a/lib/mpl_toolkits/tests/test_axes_grid1.py b/lib/mpl_toolkits/tests/test_axes_grid1.py index 33c9b0ba3066..b559dca3afe2 100644 --- a/lib/mpl_toolkits/tests/test_axes_grid1.py +++ b/lib/mpl_toolkits/tests/test_axes_grid1.py @@ -3,9 +3,11 @@ from matplotlib.externals import six +import matplotlib import matplotlib.pyplot as plt from matplotlib.testing.decorators import image_comparison -from mpl_toolkits.axes_grid1 import make_axes_locatable +from mpl_toolkits.axes_grid1 import make_axes_locatable, host_subplot +from itertools import product import numpy as np @@ -50,6 +52,36 @@ def test_divider_append_axes(): axHistleft.yaxis.set_ticklabels(()) axHistright.yaxis.set_ticklabels(()) + +@image_comparison(baseline_images=['twin_axes_empty_and_removed'], + extensions=["png"]) +def test_twin_axes_empty_and_removed(): + # Purely cosmetic font changes (avoid overlap) + matplotlib.rcParams.update({"font.size": 8}) + matplotlib.rcParams.update({"xtick.labelsize": 8}) + matplotlib.rcParams.update({"ytick.labelsize": 8}) + generators = [ "twinx", "twiny", "twin" ] + modifiers = [ "", "host invisible", "twin removed", "twin invisible", + "twin removed\nhost invisible" ] + # Unmodified host subplot at the beginning for reference + h = host_subplot(len(modifiers)+1, len(generators), 2) + h.text(0.5, 0.5, "host_subplot", horizontalalignment="center", + verticalalignment="center") + # Host subplots with various modifications (twin*, visibility) applied + for i, (mod, gen) in enumerate(product(modifiers, generators), + len(generators)+1): + h = host_subplot(len(modifiers)+1, len(generators), i) + t = getattr(h, gen)() + if "twin invisible" in mod: + t.axis[:].set_visible(False) + if "twin removed" in mod: + t.remove() + if "host invisible" in mod: + h.axis[:].set_visible(False) + h.text(0.5, 0.5, gen + ("\n" + mod if mod else ""), + horizontalalignment="center", verticalalignment="center") + plt.subplots_adjust(wspace=0.5, hspace=1) + if __name__ == '__main__': import nose nose.runmodule(argv=['-s', '--with-doctest'], exit=False)