diff --git a/doc/source/v0.15.0.txt b/doc/source/v0.15.0.txt index 4f4f0211f130c..bf959141e29b2 100644 --- a/doc/source/v0.15.0.txt +++ b/doc/source/v0.15.0.txt @@ -640,6 +640,8 @@ Bug Fixes - Bug in ``Float64Index`` where ``iat`` and ``at`` were not testing and were failing (:issue:`8092`). +- Bug in ``DataFrame.boxplot()`` where y-limits were not set correctly when + producing multiple axes (:issue:`7528`, :issue:`5517`). - Bug in ``read_csv`` where line comments were not handled correctly given a custom line terminator or ``delim_whitespace=True`` (:issue:`8122`). diff --git a/pandas/tests/test_graphics.py b/pandas/tests/test_graphics.py index ef1a640d62096..a01574c4dd146 100644 --- a/pandas/tests/test_graphics.py +++ b/pandas/tests/test_graphics.py @@ -1830,6 +1830,34 @@ def test_boxplot_return_type_legacy(self): result = df.boxplot(return_type='both') self._check_box_return_type(result, 'both') + @slow + def test_boxplot_axis_limits(self): + + def _check_ax_limits(col, ax): + y_min, y_max = ax.get_ylim() + self.assertLessEqual(y_min, col.min()) + self.assertGreaterEqual(y_max, col.max()) + + df = self.hist_df.copy() + df['age'] = np.random.randint(1, 20, df.shape[0]) + # One full row + height_ax, weight_ax = df.boxplot(['height', 'weight'], by='category') + _check_ax_limits(df['height'], height_ax) + _check_ax_limits(df['weight'], weight_ax) + self.assertEqual(weight_ax._sharey, height_ax) + + # Two rows, one partial + p = df.boxplot(['height', 'weight', 'age'], by='category') + height_ax, weight_ax, age_ax = p[0, 0], p[0, 1], p[1, 0] + dummy_ax = p[1, 1] + _check_ax_limits(df['height'], height_ax) + _check_ax_limits(df['weight'], weight_ax) + _check_ax_limits(df['age'], age_ax) + self.assertEqual(weight_ax._sharey, height_ax) + self.assertEqual(age_ax._sharey, height_ax) + self.assertIsNone(dummy_ax._sharey) + + @slow def test_kde_df(self): tm._skip_if_no_scipy() diff --git a/pandas/tools/plotting.py b/pandas/tools/plotting.py index 11f267d55fa09..07200fcab3cd4 100644 --- a/pandas/tools/plotting.py +++ b/pandas/tools/plotting.py @@ -3174,7 +3174,14 @@ def _subplots(naxes=None, sharex=False, sharey=False, squeeze=True, # Note off-by-one counting because add_subplot uses the MATLAB 1-based # convention. for i in range(1, nplots): - ax = fig.add_subplot(nrows, ncols, i + 1, **subplot_kw) + kwds = subplot_kw.copy() + # Set sharex and sharey to None for blank/dummy axes, these can + # interfere with proper axis limits on the visible axes if + # they share axes e.g. issue #7528 + if i >= naxes: + kwds['sharex'] = None + kwds['sharey'] = None + ax = fig.add_subplot(nrows, ncols, i + 1, **kwds) axarr[i] = ax if nplots > 1: