diff --git a/doc/source/whatsnew/v0.17.1.txt b/doc/source/whatsnew/v0.17.1.txt index e8078accba176..5e38d3b81abb1 100755 --- a/doc/source/whatsnew/v0.17.1.txt +++ b/doc/source/whatsnew/v0.17.1.txt @@ -102,7 +102,8 @@ Bug Fixes - Fix regression in setting of ``xticks`` in ``plot`` (:issue:`11529`). - +- Fix plotting issues when having plain ``Axes`` instances instead of + ``SubplotAxes`` (:issue:`11520`, :issue:`11556`). diff --git a/pandas/tests/test_graphics.py b/pandas/tests/test_graphics.py index 7e6aaa8213667..93f365baa86e3 100644 --- a/pandas/tests/test_graphics.py +++ b/pandas/tests/test_graphics.py @@ -3678,6 +3678,35 @@ def test_invalid_colormap(self): with tm.assertRaises(ValueError): df.plot(colormap='invalid_colormap') + def test_plain_axes(self): + + # supplied ax itself is a SubplotAxes, but figure contains also + # a plain Axes object (GH11556) + fig, ax = self.plt.subplots() + fig.add_axes([0.2, 0.2, 0.2, 0.2]) + Series(rand(10)).plot(ax=ax) + + # suppliad ax itself is a plain Axes, but because the cmap keyword + # a new ax is created for the colorbar -> also multiples axes (GH11520) + df = DataFrame({'a': randn(8), 'b': randn(8)}) + fig = self.plt.figure() + ax = fig.add_axes((0,0,1,1)) + df.plot(kind='scatter', ax=ax, x='a', y='b', c='a', cmap='hsv') + + # other examples + fig, ax = self.plt.subplots() + from mpl_toolkits.axes_grid1 import make_axes_locatable + divider = make_axes_locatable(ax) + cax = divider.append_axes("right", size="5%", pad=0.05) + Series(rand(10)).plot(ax=ax) + Series(rand(10)).plot(ax=cax) + + fig, ax = self.plt.subplots() + from mpl_toolkits.axes_grid.inset_locator import inset_axes + iax = inset_axes(ax, width="30%", height=1., loc=3) + Series(rand(10)).plot(ax=ax) + Series(rand(10)).plot(ax=iax) + @tm.mplskip class TestDataFrameGroupByPlots(TestPlotBase): diff --git a/pandas/tools/plotting.py b/pandas/tools/plotting.py index c6a29c7d5bb9d..4570dc24151c7 100644 --- a/pandas/tools/plotting.py +++ b/pandas/tools/plotting.py @@ -1135,7 +1135,7 @@ def _post_plot_logic(self, ax, data): def _adorn_subplots(self): """Common post process unrelated to data""" if len(self.axes) > 0: - all_axes = self._get_axes() + all_axes = self._get_subplots() nrows, ncols = self._get_axes_layout() _handle_shared_axes(axarr=all_axes, nplots=len(all_axes), naxes=nrows * ncols, nrows=nrows, @@ -1467,11 +1467,13 @@ def _get_errorbars(self, label=None, index=None, xerr=True, yerr=True): errors[kw] = err return errors - def _get_axes(self): - return self.axes[0].get_figure().get_axes() + def _get_subplots(self): + from matplotlib.axes import Subplot + return [ax for ax in self.axes[0].get_figure().get_axes() + if isinstance(ax, Subplot)] def _get_axes_layout(self): - axes = self._get_axes() + axes = self._get_subplots() x_set = set() y_set = set() for ax in axes: