diff --git a/doc/source/visualization.rst b/doc/source/visualization.rst index 7f8d0e529fc8b..6bef7f6f456c8 100644 --- a/doc/source/visualization.rst +++ b/doc/source/visualization.rst @@ -387,7 +387,6 @@ The existing interface ``DataFrame.boxplot`` to plot boxplot still can be used. np.random.seed(123456) .. ipython:: python - :okwarning: df = DataFrame(rand(10,5)) plt.figure(); @@ -1271,7 +1270,7 @@ or columns needed, given the other. .. ipython:: python @savefig frame_plot_subplots_layout.png - df.plot(subplots=True, layout=(3, 2), figsize=(6, 6), sharex=False); + df.plot(subplots=True, layout=(2, 3), figsize=(6, 6), sharex=False); .. ipython:: python :suppress: @@ -1282,22 +1281,23 @@ The above example is identical to using .. ipython:: python - df.plot(subplots=True, layout=(3, -1), figsize=(6, 6), sharex=False); + df.plot(subplots=True, layout=(2, -1), figsize=(6, 6), sharex=False); .. ipython:: python :suppress: plt.close('all') -The required number of columns (2) is inferred from the number of series to plot -and the given number of rows (3). +The required number of columns (3) is inferred from the number of series to plot +and the given number of rows (2). Also, you can pass multiple axes created beforehand as list-like via ``ax`` keyword. This allows to use more complicated layout. The passed axes must be the same number as the subplots being drawn. -When multiple axes are passed via ``ax`` keyword, ``layout``, ``sharex`` and ``sharey`` keywords are ignored. -These must be configured when creating axes. +When multiple axes are passed via ``ax`` keyword, ``layout``, ``sharex`` and ``sharey`` keywords +don't affect to the output. You should explicitly pass ``sharex=False`` and ``sharey=False``, +otherwise you will see a warning. .. ipython:: python @@ -1306,9 +1306,9 @@ These must be configured when creating axes. target1 = [axes[0][0], axes[1][1], axes[2][2], axes[3][3]] target2 = [axes[3][0], axes[2][1], axes[1][2], axes[0][3]] - df.plot(subplots=True, ax=target1, legend=False); + df.plot(subplots=True, ax=target1, legend=False, sharex=False, sharey=False); @savefig frame_plot_subplots_multi_ax.png - (-df).plot(subplots=True, ax=target2, legend=False); + (-df).plot(subplots=True, ax=target2, legend=False, sharex=False, sharey=False); .. ipython:: python :suppress: diff --git a/pandas/tests/test_graphics.py b/pandas/tests/test_graphics.py index 4195baf4874f1..591ef8081d878 100644 --- a/pandas/tests/test_graphics.py +++ b/pandas/tests/test_graphics.py @@ -5,6 +5,7 @@ import itertools import os import string +import warnings from distutils.version import LooseVersion from datetime import datetime, date @@ -1297,12 +1298,12 @@ def test_subplots_multiple_axes(self): df = DataFrame(np.random.rand(10, 3), index=list(string.ascii_letters[:10])) - returned = df.plot(subplots=True, ax=axes[0]) + returned = df.plot(subplots=True, ax=axes[0], sharex=False, sharey=False) self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) self.assertEqual(returned.shape, (3, )) self.assertIs(returned[0].figure, fig) # draw on second row - returned = df.plot(subplots=True, ax=axes[1]) + returned = df.plot(subplots=True, ax=axes[1], sharex=False, sharey=False) self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) self.assertEqual(returned.shape, (3, )) self.assertIs(returned[0].figure, fig) @@ -1319,18 +1320,23 @@ def test_subplots_multiple_axes(self): # (show warning is tested in # TestDataFrameGroupByPlots.test_grouped_box_multiple_axes fig, axes = self.plt.subplots(2, 2) - df = DataFrame(np.random.rand(10, 4), - index=list(string.ascii_letters[:10])) - - returned = df.plot(subplots=True, ax=axes, layout=(2, 1)) - self._check_axes_shape(returned, axes_num=4, layout=(2, 2)) - self.assertEqual(returned.shape, (4, )) - - returned = df.plot(subplots=True, ax=axes, layout=(2, -1)) - self._check_axes_shape(returned, axes_num=4, layout=(2, 2)) - self.assertEqual(returned.shape, (4, )) - - returned = df.plot(subplots=True, ax=axes, layout=(-1, 2)) + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + df = DataFrame(np.random.rand(10, 4), + index=list(string.ascii_letters[:10])) + + returned = df.plot(subplots=True, ax=axes, layout=(2, 1), + sharex=False, sharey=False) + self._check_axes_shape(returned, axes_num=4, layout=(2, 2)) + self.assertEqual(returned.shape, (4, )) + + returned = df.plot(subplots=True, ax=axes, layout=(2, -1), + sharex=False, sharey=False) + self._check_axes_shape(returned, axes_num=4, layout=(2, 2)) + self.assertEqual(returned.shape, (4, )) + + returned = df.plot(subplots=True, ax=axes, layout=(-1, 2), + sharex=False, sharey=False) self._check_axes_shape(returned, axes_num=4, layout=(2, 2)) self.assertEqual(returned.shape, (4, )) @@ -1338,7 +1344,8 @@ def test_subplots_multiple_axes(self): fig, axes = self.plt.subplots(1, 1) df = DataFrame(np.random.rand(10, 1), index=list(string.ascii_letters[:10])) - axes = df.plot(subplots=True, ax=[axes]) + + axes = df.plot(subplots=True, ax=[axes], sharex=False, sharey=False) self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) self.assertEqual(axes.shape, (1, )) @@ -3122,13 +3129,14 @@ class TestDataFrameGroupByPlots(TestPlotBase): @slow def test_boxplot(self): grouped = self.hist_df.groupby(by='gender') - axes = _check_plot_works(grouped.boxplot, return_type='axes') + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + axes = _check_plot_works(grouped.boxplot, return_type='axes') self._check_axes_shape(list(axes.values()), axes_num=2, layout=(1, 2)) axes = _check_plot_works(grouped.boxplot, subplots=False, return_type='axes') self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) - tuples = lzip(string.ascii_letters[:10], range(10)) df = DataFrame(np.random.rand(10, 3), index=MultiIndex.from_tuples(tuples)) @@ -3149,6 +3157,30 @@ def test_boxplot(self): return_type='axes') self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) + @slow + def test_grouped_plot_fignums(self): + n = 10 + weight = Series(np.random.normal(166, 20, size=n)) + height = Series(np.random.normal(60, 10, size=n)) + with tm.RNGContext(42): + gender = tm.choice(['male', 'female'], size=n) + df = DataFrame({'height': height, 'weight': weight, 'gender': gender}) + gb = df.groupby('gender') + + res = gb.plot() + self.assertEqual(len(self.plt.get_fignums()), 2) + self.assertEqual(len(res), 2) + tm.close() + + res = gb.boxplot(return_type='axes') + self.assertEqual(len(self.plt.get_fignums()), 1) + self.assertEqual(len(res), 2) + tm.close() + + # now works with GH 5610 as gender is excluded + res = df.groupby('gender').hist() + tm.close() + def test_series_plot_color_kwargs(self): # GH1890 ax = Series(np.arange(12) + 1).plot(color='green') @@ -3219,6 +3251,21 @@ def test_grouped_hist(self): with tm.assert_produces_warning(FutureWarning): df.hist(by='C', figsize='default') + @slow + def test_grouped_hist2(self): + n = 10 + weight = Series(np.random.normal(166, 20, size=n)) + height = Series(np.random.normal(60, 10, size=n)) + with tm.RNGContext(42): + gender_int = tm.choice([0, 1], size=n) + df_int = DataFrame({'height': height, 'weight': weight, + 'gender': gender_int}) + gb = df_int.groupby('gender') + axes = gb.hist() + self.assertEqual(len(axes), 2) + self.assertEqual(len(self.plt.get_fignums()), 2) + tm.close() + @slow def test_grouped_box_return_type(self): df = self.hist_df @@ -3334,15 +3381,21 @@ def test_grouped_box_multiple_axes(self): self._check_axes_shape(self.plt.gcf().axes, axes_num=4, layout=(2, 2)) fig, axes = self.plt.subplots(2, 3) - returned = df.boxplot(column=['height', 'weight', 'category'], by='gender', - return_type='axes', ax=axes[0]) + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + returned = df.boxplot(column=['height', 'weight', 'category'], + by='gender', return_type='axes', ax=axes[0]) returned = np.array(list(returned.values())) self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) self.assert_numpy_array_equal(returned, axes[0]) self.assertIs(returned[0].figure, fig) + # draw on second row - returned = df.groupby('classroom').boxplot(column=['height', 'weight', 'category'], - return_type='axes', ax=axes[1]) + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + returned = df.groupby('classroom').boxplot( + column=['height', 'weight', 'category'], + return_type='axes', ax=axes[1]) returned = np.array(list(returned.values())) self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) self.assert_numpy_array_equal(returned, axes[1]) @@ -3469,6 +3522,32 @@ def test_invalid_colormap(self): with tm.assertRaises(ValueError): df.plot(colormap='invalid_colormap') + def test_series_groupby_plotting_nominally_works(self): + n = 10 + weight = Series(np.random.normal(166, 20, size=n)) + height = Series(np.random.normal(60, 10, size=n)) + with tm.RNGContext(42): + gender = tm.choice(['male', 'female'], size=n) + + weight.groupby(gender).plot() + tm.close() + height.groupby(gender).hist() + tm.close() + #Regression test for GH8733 + height.groupby(gender).plot(alpha=0.5) + tm.close() + + def test_plotting_with_float_index_works(self): + # GH 7025 + df = DataFrame({'def': [1,1,1,2,2,2,3,3,3], + 'val': np.random.randn(9)}, + index=[1.0,2.0,3.0,1.0,2.0,3.0,1.0,2.0,3.0]) + + df.groupby('def')['val'].plot() + tm.close() + df.groupby('def')['val'].apply(lambda x: x.plot()) + tm.close() + def assert_is_valid_plot_return_object(objs): import matplotlib.pyplot as plt diff --git a/pandas/tests/test_groupby.py b/pandas/tests/test_groupby.py index 1d309e2a6389f..a9c3d47656ee5 100644 --- a/pandas/tests/test_groupby.py +++ b/pandas/tests/test_groupby.py @@ -35,11 +35,6 @@ import pandas as pd from numpy.testing import assert_equal -def _skip_if_mpl_not_installed(): - try: - import matplotlib.pyplot as plt - except ImportError: - raise nose.SkipTest("matplotlib not installed") def commonSetUp(self): self.dateRange = bdate_range('1/1/2005', periods=250) @@ -4653,88 +4648,6 @@ def test_groupby_blacklist(self): with tm.assertRaisesRegexp(AttributeError, msg): getattr(gb, bl) - def test_series_groupby_plotting_nominally_works(self): - _skip_if_mpl_not_installed() - - n = 10 - weight = Series(np.random.normal(166, 20, size=n)) - height = Series(np.random.normal(60, 10, size=n)) - with tm.RNGContext(42): - gender = tm.choice(['male', 'female'], size=n) - - weight.groupby(gender).plot() - tm.close() - height.groupby(gender).hist() - tm.close() - #Regression test for GH8733 - height.groupby(gender).plot(alpha=0.5) - tm.close() - - def test_plotting_with_float_index_works(self): - _skip_if_mpl_not_installed() - - # GH 7025 - df = DataFrame({'def': [1,1,1,2,2,2,3,3,3], - 'val': np.random.randn(9)}, - index=[1.0,2.0,3.0,1.0,2.0,3.0,1.0,2.0,3.0]) - - df.groupby('def')['val'].plot() - tm.close() - df.groupby('def')['val'].apply(lambda x: x.plot()) - tm.close() - - @slow - def test_frame_groupby_plot_boxplot(self): - _skip_if_mpl_not_installed() - - import matplotlib.pyplot as plt - import matplotlib as mpl - mpl.use('Agg') - tm.close() - - n = 10 - weight = Series(np.random.normal(166, 20, size=n)) - height = Series(np.random.normal(60, 10, size=n)) - with tm.RNGContext(42): - gender = tm.choice(['male', 'female'], size=n) - df = DataFrame({'height': height, 'weight': weight, 'gender': gender}) - gb = df.groupby('gender') - - res = gb.plot() - self.assertEqual(len(plt.get_fignums()), 2) - self.assertEqual(len(res), 2) - tm.close() - - res = gb.boxplot() - self.assertEqual(len(plt.get_fignums()), 1) - self.assertEqual(len(res), 2) - tm.close() - - # now works with GH 5610 as gender is excluded - res = df.groupby('gender').hist() - tm.close() - - @slow - def test_frame_groupby_hist(self): - _skip_if_mpl_not_installed() - import matplotlib.pyplot as plt - import matplotlib as mpl - mpl.use('Agg') - tm.close() - - n = 10 - weight = Series(np.random.normal(166, 20, size=n)) - height = Series(np.random.normal(60, 10, size=n)) - with tm.RNGContext(42): - gender_int = tm.choice([0, 1], size=n) - df_int = DataFrame({'height': height, 'weight': weight, - 'gender': gender_int}) - gb = df_int.groupby('gender') - axes = gb.hist() - self.assertEqual(len(axes), 2) - self.assertEqual(len(plt.get_fignums()), 2) - tm.close() - def test_tab_completion(self): grp = self.mframe.groupby(level='second') results = set([v for v in dir(grp) if not v.startswith('_')])