From a7d0654fccbbe16ee436caaef63299bc779c0c5a Mon Sep 17 00:00:00 2001 From: Julia Signell Date: Wed, 25 Sep 2019 15:34:45 -0400 Subject: [PATCH 01/11] Allow backend to be an option --- pandas/plotting/_core.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py index 127fdffafcf36..1d7663f23626b 100644 --- a/pandas/plotting/_core.py +++ b/pandas/plotting/_core.py @@ -62,7 +62,7 @@ def hist_series( -------- matplotlib.axes.Axes.hist : Plot a histogram using matplotlib. """ - plot_backend = _get_plot_backend() + plot_backend = _get_plot_backend(kwds.pop('backend', None)) return plot_backend.hist_series( self, by=by, @@ -172,7 +172,7 @@ def hist_frame( ... }, index=['pig', 'rabbit', 'duck', 'chicken', 'horse']) >>> hist = df.hist(bins=3) """ - plot_backend = _get_plot_backend() + plot_backend = _get_plot_backend(kwds.pop('backend', None)) return plot_backend.hist_frame( data, column=column, @@ -367,7 +367,7 @@ def boxplot( >>> type(boxplot) """ - plot_backend = _get_plot_backend("matplotlib") + plot_backend = _get_plot_backend(kwds.pop('backend', None)) return plot_backend.boxplot( data, column=column, @@ -397,7 +397,7 @@ def boxplot_frame( return_type=None, **kwargs ): - plot_backend = _get_plot_backend() + plot_backend = _get_plot_backend(kwds.pop('backend', None)) return plot_backend.boxplot_frame( self, column=column, @@ -477,7 +477,7 @@ def boxplot_frame_groupby( >>> grouped = df.unstack(level='lvl1').groupby(level=0, axis=1) >>> boxplot_frame_groupby(grouped, subplots=False) """ - plot_backend = _get_plot_backend() + plot_backend = _get_plot_backend(kwds.pop('backend', None)) return plot_backend.boxplot_frame_groupby( grouped, subplots=subplots, @@ -713,7 +713,7 @@ def _get_call_args(backend_name, data, args, kwargs): return x, y, kind, kwargs def __call__(self, *args, **kwargs): - plot_backend = _get_plot_backend() + plot_backend = _get_plot_backend(kwds.pop('backend', None)) x, y, kind, kwargs = self._get_call_args( plot_backend.__name__, self._parent, args, kwargs From 12819425c6eab151c8f79bc26d4d35d712f4f1f6 Mon Sep 17 00:00:00 2001 From: Julia Signell Date: Wed, 25 Sep 2019 15:44:55 -0400 Subject: [PATCH 02/11] Black and flake --- pandas/plotting/_core.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py index 1d7663f23626b..c9645932f6cd2 100644 --- a/pandas/plotting/_core.py +++ b/pandas/plotting/_core.py @@ -62,7 +62,7 @@ def hist_series( -------- matplotlib.axes.Axes.hist : Plot a histogram using matplotlib. """ - plot_backend = _get_plot_backend(kwds.pop('backend', None)) + plot_backend = _get_plot_backend(kwds.pop("backend", None)) return plot_backend.hist_series( self, by=by, @@ -172,7 +172,7 @@ def hist_frame( ... }, index=['pig', 'rabbit', 'duck', 'chicken', 'horse']) >>> hist = df.hist(bins=3) """ - plot_backend = _get_plot_backend(kwds.pop('backend', None)) + plot_backend = _get_plot_backend(kwds.pop("backend", None)) return plot_backend.hist_frame( data, column=column, @@ -367,7 +367,7 @@ def boxplot( >>> type(boxplot) """ - plot_backend = _get_plot_backend(kwds.pop('backend', None)) + plot_backend = _get_plot_backend(kwds.pop("backend", None)) return plot_backend.boxplot( data, column=column, @@ -397,7 +397,7 @@ def boxplot_frame( return_type=None, **kwargs ): - plot_backend = _get_plot_backend(kwds.pop('backend', None)) + plot_backend = _get_plot_backend(kwds.pop("backend", None)) return plot_backend.boxplot_frame( self, column=column, @@ -477,7 +477,7 @@ def boxplot_frame_groupby( >>> grouped = df.unstack(level='lvl1').groupby(level=0, axis=1) >>> boxplot_frame_groupby(grouped, subplots=False) """ - plot_backend = _get_plot_backend(kwds.pop('backend', None)) + plot_backend = _get_plot_backend(kwds.pop("backend", None)) return plot_backend.boxplot_frame_groupby( grouped, subplots=subplots, @@ -713,7 +713,7 @@ def _get_call_args(backend_name, data, args, kwargs): return x, y, kind, kwargs def __call__(self, *args, **kwargs): - plot_backend = _get_plot_backend(kwds.pop('backend', None)) + plot_backend = _get_plot_backend(kwargs.pop("backend", None)) x, y, kind, kwargs = self._get_call_args( plot_backend.__name__, self._parent, args, kwargs From 614232ce8fac01c1216089c0497203cd1363fb99 Mon Sep 17 00:00:00 2001 From: Julia Signell Date: Wed, 25 Sep 2019 16:32:44 -0400 Subject: [PATCH 03/11] Adding a test for passing backend option in plot --- pandas/tests/plotting/test_backend.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pandas/tests/plotting/test_backend.py b/pandas/tests/plotting/test_backend.py index 41b1a88b15acb..47a0cb0302af2 100644 --- a/pandas/tests/plotting/test_backend.py +++ b/pandas/tests/plotting/test_backend.py @@ -9,7 +9,7 @@ import pandas dummy_backend = types.ModuleType("pandas_dummy_backend") -setattr(dummy_backend, "plot", lambda *args, **kwargs: None) +setattr(dummy_backend, "plot", lambda *args, **kwargs: 'used_dummy') @pytest.fixture @@ -38,6 +38,16 @@ def test_backend_is_correct(monkeypatch, restore_backend): ) +def test_backend_can_be_set_in_plot_call(monkeypatch, restore_backend): + monkeypatch.setitem(sys.modules, "pandas_dummy_backend", dummy_backend) + df = pandas.DataFrame([1,2,3]) + + assert pandas.get_option("plotting.backend") == "matplotlib" + assert ( + df.plot(backend='pandas_dummy_backend') == 'used_dummy' + ) + + @td.skip_if_no_mpl def test_register_entrypoint(restore_backend): From 4d15f4ecc3e670712149220f0f5c8a32e8cab36c Mon Sep 17 00:00:00 2001 From: Julia Signell Date: Wed, 25 Sep 2019 16:33:00 -0400 Subject: [PATCH 04/11] Added line in whatsnew --- doc/source/whatsnew/v1.0.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index 4007ecd5a9412..eb2fe7b08a4d3 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -398,6 +398,7 @@ Plotting - Bug where :meth:`DataFrame.boxplot` would not accept a `color` parameter like `DataFrame.plot.box` (:issue:`26214`) - Bug in the ``xticks`` argument being ignored for :meth:`DataFrame.plot.bar` (:issue:`14119`) - :func:`set_option` now validates that the plot backend provided to ``'plotting.backend'`` implements the backend when the option is set, rather than when a plot is created (:issue:`28163`) +- Allow users to pass new backend options directly in :meth:`.plot` calls (:issue:`28619`). Groupby/resample/rolling ^^^^^^^^^^^^^^^^^^^^^^^^ From eda5bbbbbc1c00aac14e0b2ba1996269998cd7b7 Mon Sep 17 00:00:00 2001 From: Julia Signell Date: Wed, 25 Sep 2019 16:34:46 -0400 Subject: [PATCH 05/11] Black --- pandas/tests/plotting/test_backend.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pandas/tests/plotting/test_backend.py b/pandas/tests/plotting/test_backend.py index 47a0cb0302af2..c84b78c79e771 100644 --- a/pandas/tests/plotting/test_backend.py +++ b/pandas/tests/plotting/test_backend.py @@ -9,7 +9,7 @@ import pandas dummy_backend = types.ModuleType("pandas_dummy_backend") -setattr(dummy_backend, "plot", lambda *args, **kwargs: 'used_dummy') +setattr(dummy_backend, "plot", lambda *args, **kwargs: "used_dummy") @pytest.fixture @@ -40,12 +40,10 @@ def test_backend_is_correct(monkeypatch, restore_backend): def test_backend_can_be_set_in_plot_call(monkeypatch, restore_backend): monkeypatch.setitem(sys.modules, "pandas_dummy_backend", dummy_backend) - df = pandas.DataFrame([1,2,3]) + df = pandas.DataFrame([1, 2, 3]) assert pandas.get_option("plotting.backend") == "matplotlib" - assert ( - df.plot(backend='pandas_dummy_backend') == 'used_dummy' - ) + assert df.plot(backend="pandas_dummy_backend") == "used_dummy" @td.skip_if_no_mpl From 9041fb13c30a4b4386f9835dbe66e0986d6b5a00 Mon Sep 17 00:00:00 2001 From: Julia Signell Date: Wed, 25 Sep 2019 16:38:33 -0400 Subject: [PATCH 06/11] Write in 1.0.0 instead of 0.25.2 --- doc/source/whatsnew/v1.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index eb2fe7b08a4d3..bebae2b0f18c8 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -398,7 +398,7 @@ Plotting - Bug where :meth:`DataFrame.boxplot` would not accept a `color` parameter like `DataFrame.plot.box` (:issue:`26214`) - Bug in the ``xticks`` argument being ignored for :meth:`DataFrame.plot.bar` (:issue:`14119`) - :func:`set_option` now validates that the plot backend provided to ``'plotting.backend'`` implements the backend when the option is set, rather than when a plot is created (:issue:`28163`) -- Allow users to pass new backend options directly in :meth:`.plot` calls (:issue:`28619`). +- :meth:`.plot` now allows a ``backend`` kwarg to allow changing between backends in one session (:issue:`28619`). Groupby/resample/rolling ^^^^^^^^^^^^^^^^^^^^^^^^ From 06236b9dee362e391e19bbbe4fe69e805734d2f8 Mon Sep 17 00:00:00 2001 From: Julia Signell Date: Thu, 26 Sep 2019 09:20:18 -0400 Subject: [PATCH 07/11] Update doc/source/whatsnew/v1.0.0.rst Co-Authored-By: Tom Augspurger --- doc/source/whatsnew/v1.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index bebae2b0f18c8..f90c2c2725991 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -398,7 +398,7 @@ Plotting - Bug where :meth:`DataFrame.boxplot` would not accept a `color` parameter like `DataFrame.plot.box` (:issue:`26214`) - Bug in the ``xticks`` argument being ignored for :meth:`DataFrame.plot.bar` (:issue:`14119`) - :func:`set_option` now validates that the plot backend provided to ``'plotting.backend'`` implements the backend when the option is set, rather than when a plot is created (:issue:`28163`) -- :meth:`.plot` now allows a ``backend`` kwarg to allow changing between backends in one session (:issue:`28619`). +- :meth:`DataFrame.plot` now allow a ``backend`` keyword arugment to allow changing between backends in one session (:issue:`28619`). Groupby/resample/rolling ^^^^^^^^^^^^^^^^^^^^^^^^ From d2fc7a81f6b58e9c16014058a791bf75138bd0ee Mon Sep 17 00:00:00 2001 From: Julia Signell Date: Thu, 26 Sep 2019 09:23:42 -0400 Subject: [PATCH 08/11] Re-hardcoding matplotlib for boxplots --- pandas/plotting/_core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py index c9645932f6cd2..b493710ad9fb9 100644 --- a/pandas/plotting/_core.py +++ b/pandas/plotting/_core.py @@ -367,7 +367,7 @@ def boxplot( >>> type(boxplot) """ - plot_backend = _get_plot_backend(kwds.pop("backend", None)) + plot_backend = _get_plot_backend("matplotlib") return plot_backend.boxplot( data, column=column, From 0a7800b8d5a4ce9763db9c9d74637862e727dc36 Mon Sep 17 00:00:00 2001 From: Julia Signell Date: Thu, 26 Sep 2019 09:55:10 -0400 Subject: [PATCH 09/11] Adding backend to docstrings and signatures --- pandas/plotting/_core.py | 202 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 195 insertions(+), 7 deletions(-) diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py index b493710ad9fb9..aaa2e93c277cc 100644 --- a/pandas/plotting/_core.py +++ b/pandas/plotting/_core.py @@ -3,8 +3,6 @@ from pandas._config import get_option -from pandas.util._decorators import Appender - from pandas.core.dtypes.common import is_integer, is_list_like from pandas.core.dtypes.generic import ABCDataFrame, ABCSeries @@ -22,6 +20,7 @@ def hist_series( yrot=None, figsize=None, bins=10, + backend=None, **kwargs ): """ @@ -50,6 +49,11 @@ def hist_series( bin edges are calculated and returned. If bins is a sequence, gives bin edges, including left edge of first bin and right edge of last bin. In this case, bins is returned unmodified. + backend : str, default None + Backend to use instead of the backend specified in the option + ``plotting.backend``. For instance, 'matplotlib'. Alternatively, to + specify the ``plotting.backend`` for the whole session, set + ``pd.options.plotting.backend``. **kwargs To be passed to the actual plotting function. @@ -62,7 +66,7 @@ def hist_series( -------- matplotlib.axes.Axes.hist : Plot a histogram using matplotlib. """ - plot_backend = _get_plot_backend(kwds.pop("backend", None)) + plot_backend = _get_plot_backend(backend) return plot_backend.hist_series( self, by=by, @@ -93,6 +97,7 @@ def hist_frame( figsize=None, layout=None, bins=10, + backend=None, **kwargs ): """ @@ -145,6 +150,11 @@ def hist_frame( bin edges are calculated and returned. If bins is a sequence, gives bin edges, including left edge of first bin and right edge of last bin. In this case, bins is returned unmodified. + backend : str, default None + Backend to use instead of the backend specified in the option + ``plotting.backend``. For instance, 'matplotlib'. Alternatively, to + specify the ``plotting.backend`` for the whole session, set + ``pd.options.plotting.backend``. **kwargs All other plotting keyword arguments to be passed to :meth:`matplotlib.pyplot.hist`. @@ -172,7 +182,7 @@ def hist_frame( ... }, index=['pig', 'rabbit', 'duck', 'chicken', 'horse']) >>> hist = df.hist(bins=3) """ - plot_backend = _get_plot_backend(kwds.pop("backend", None)) + plot_backend = _get_plot_backend(backend) return plot_backend.hist_frame( data, column=column, @@ -383,7 +393,6 @@ def boxplot( ) -@Appender(boxplot.__doc__) def boxplot_frame( self, column=None, @@ -395,9 +404,177 @@ def boxplot_frame( figsize=None, layout=None, return_type=None, + backend=None, **kwargs ): - plot_backend = _get_plot_backend(kwds.pop("backend", None)) + """ + Make a box plot from DataFrame columns. + + Make a box-and-whisker plot from DataFrame columns, optionally grouped + by some other columns. A box plot is a method for graphically depicting + groups of numerical data through their quartiles. + The box extends from the Q1 to Q3 quartile values of the data, + with a line at the median (Q2). The whiskers extend from the edges + of box to show the range of the data. The position of the whiskers + is set by default to `1.5 * IQR (IQR = Q3 - Q1)` from the edges of the box. + Outlier points are those past the end of the whiskers. + + For further details see + Wikipedia's entry for `boxplot `_. + + Parameters + ---------- + column : str or list of str, optional + Column name or list of names, or vector. + Can be any valid input to :meth:`pandas.DataFrame.groupby`. + by : str or array-like, optional + Column in the DataFrame to :meth:`pandas.DataFrame.groupby`. + One box-plot will be done per value of columns in `by`. + ax : object of class matplotlib.axes.Axes, optional + The matplotlib axes to be used by boxplot. + fontsize : float or str + Tick label font size in points or as a string (e.g., `large`). + rot : int or float, default 0 + The rotation angle of labels (in degrees) + with respect to the screen coordinate system. + grid : bool, default True + Setting this to True will show the grid. + figsize : A tuple (width, height) in inches + The size of the figure to create in matplotlib. + layout : tuple (rows, columns), optional + For example, (3, 5) will display the subplots + using 3 columns and 5 rows, starting from the top-left. + return_type : {'axes', 'dict', 'both'} or None, default 'axes' + The kind of object to return. The default is ``axes``. + + * 'axes' returns the matplotlib axes the boxplot is drawn on. + * 'dict' returns a dictionary whose values are the matplotlib + Lines of the boxplot. + * 'both' returns a namedtuple with the axes and dict. + * when grouping with ``by``, a Series mapping columns to + ``return_type`` is returned. + + If ``return_type`` is `None`, a NumPy array + of axes with the same shape as ``layout`` is returned. + backend : str, default None + Backend to use instead of the backend specified in the option + ``plotting.backend``. For instance, 'matplotlib'. Alternatively, to + specify the ``plotting.backend`` for the whole session, set + ``pd.options.plotting.backend``. + **kwds + All other plotting keyword arguments to be passed to + :func:`matplotlib.pyplot.boxplot`. + + Returns + ------- + result + See Notes. + + See Also + -------- + Series.plot.hist: Make a histogram. + matplotlib.pyplot.boxplot : Matplotlib equivalent plot. + + Notes + ----- + The return type depends on the `return_type` parameter: + + * 'axes' : object of class matplotlib.axes.Axes + * 'dict' : dict of matplotlib.lines.Line2D objects + * 'both' : a namedtuple with structure (ax, lines) + + For data grouped with ``by``, return a Series of the above or a numpy + array: + + * :class:`~pandas.Series` + * :class:`~numpy.array` (for ``return_type = None``) + + Use ``return_type='dict'`` when you want to tweak the appearance + of the lines after plotting. In this case a dict containing the Lines + making up the boxes, caps, fliers, medians, and whiskers is returned. + + Examples + -------- + + Boxplots can be created for every column in the dataframe + by ``df.boxplot()`` or indicating the columns to be used: + + .. plot:: + :context: close-figs + + >>> np.random.seed(1234) + >>> df = pd.DataFrame(np.random.randn(10,4), + ... columns=['Col1', 'Col2', 'Col3', 'Col4']) + >>> boxplot = df.boxplot(column=['Col1', 'Col2', 'Col3']) + + Boxplots of variables distributions grouped by the values of a third + variable can be created using the option ``by``. For instance: + + .. plot:: + :context: close-figs + + >>> df = pd.DataFrame(np.random.randn(10, 2), + ... columns=['Col1', 'Col2']) + >>> df['X'] = pd.Series(['A', 'A', 'A', 'A', 'A', + ... 'B', 'B', 'B', 'B', 'B']) + >>> boxplot = df.boxplot(by='X') + + A list of strings (i.e. ``['X', 'Y']``) can be passed to boxplot + in order to group the data by combination of the variables in the x-axis: + + .. plot:: + :context: close-figs + + >>> df = pd.DataFrame(np.random.randn(10,3), + ... columns=['Col1', 'Col2', 'Col3']) + >>> df['X'] = pd.Series(['A', 'A', 'A', 'A', 'A', + ... 'B', 'B', 'B', 'B', 'B']) + >>> df['Y'] = pd.Series(['A', 'B', 'A', 'B', 'A', + ... 'B', 'A', 'B', 'A', 'B']) + >>> boxplot = df.boxplot(column=['Col1', 'Col2'], by=['X', 'Y']) + + The layout of boxplot can be adjusted giving a tuple to ``layout``: + + .. plot:: + :context: close-figs + + >>> boxplot = df.boxplot(column=['Col1', 'Col2'], by='X', + ... layout=(2, 1)) + + Additional formatting can be done to the boxplot, like suppressing the grid + (``grid=False``), rotating the labels in the x-axis (i.e. ``rot=45``) + or changing the fontsize (i.e. ``fontsize=15``): + + .. plot:: + :context: close-figs + + >>> boxplot = df.boxplot(grid=False, rot=45, fontsize=15) + + The parameter ``return_type`` can be used to select the type of element + returned by `boxplot`. When ``return_type='axes'`` is selected, + the matplotlib axes on which the boxplot is drawn are returned: + + >>> boxplot = df.boxplot(column=['Col1','Col2'], return_type='axes') + >>> type(boxplot) + + + When grouping with ``by``, a Series mapping columns to ``return_type`` + is returned: + + >>> boxplot = df.boxplot(column=['Col1', 'Col2'], by='X', + ... return_type='axes') + >>> type(boxplot) + + + If ``return_type`` is `None`, a NumPy array of axes with the same shape + as ``layout`` is returned: + + >>> boxplot = df.boxplot(column=['Col1', 'Col2'], by='X', + ... return_type=None) + >>> type(boxplot) + + """ + plot_backend = _get_plot_backend(backend) return plot_backend.boxplot_frame( self, column=column, @@ -425,6 +602,7 @@ def boxplot_frame_groupby( layout=None, sharex=False, sharey=True, + backend=None, **kwargs ): """ @@ -454,6 +632,11 @@ def boxplot_frame_groupby( Whether y-axes will be shared among subplots. .. versionadded:: 0.23.1 + backend : str, default None + Backend to use instead of the backend specified in the option + ``plotting.backend``. For instance, 'matplotlib'. Alternatively, to + specify the ``plotting.backend`` for the whole session, set + ``pd.options.plotting.backend``. **kwargs All other plotting keyword arguments to be passed to matplotlib's boxplot function. @@ -477,7 +660,7 @@ def boxplot_frame_groupby( >>> grouped = df.unstack(level='lvl1').groupby(level=0, axis=1) >>> boxplot_frame_groupby(grouped, subplots=False) """ - plot_backend = _get_plot_backend(kwds.pop("backend", None)) + plot_backend = _get_plot_backend(backend) return plot_backend.boxplot_frame_groupby( grouped, subplots=subplots, @@ -584,6 +767,11 @@ class PlotAccessor(PandasObject): labels with "(right)" in the legend. include_bool : bool, default is False If True, boolean values can be plotted. + backend : str, default None + Backend to use instead of the backend specified in the option + ``plotting.backend``. For instance, 'matplotlib'. Alternatively, to + specify the ``plotting.backend`` for the whole session, set + ``pd.options.plotting.backend``. **kwargs Options to pass to matplotlib plotting method. From accd05b31056092fb1d1eaa342bdce9d29606079 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Tue, 5 Nov 2019 09:37:14 -0500 Subject: [PATCH 10/11] fixup doc --- pandas/plotting/_core.py | 510 ++++++++++++++------------------------- 1 file changed, 181 insertions(+), 329 deletions(-) diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py index 4097d394c52d7..f663dec456eb6 100644 --- a/pandas/plotting/_core.py +++ b/pandas/plotting/_core.py @@ -3,6 +3,8 @@ from pandas._config import get_option +from pandas.util._decorators import Appender, Substitution + from pandas.core.dtypes.common import is_integer, is_list_like from pandas.core.dtypes.generic import ABCDataFrame, ABCSeries @@ -202,181 +204,196 @@ def hist_frame( ) -def boxplot( - data, - column=None, - by=None, - ax=None, - fontsize=None, - rot=0, - grid=True, - figsize=None, - layout=None, - return_type=None, - **kwargs -): - """ - Make a box plot from DataFrame columns. - - Make a box-and-whisker plot from DataFrame columns, optionally grouped - by some other columns. A box plot is a method for graphically depicting - groups of numerical data through their quartiles. - The box extends from the Q1 to Q3 quartile values of the data, - with a line at the median (Q2). The whiskers extend from the edges - of box to show the range of the data. The position of the whiskers - is set by default to `1.5 * IQR (IQR = Q3 - Q1)` from the edges of the box. - Outlier points are those past the end of the whiskers. - - For further details see - Wikipedia's entry for `boxplot `_. +_boxplot_doc = """ +Make a box plot from DataFrame columns. + +Make a box-and-whisker plot from DataFrame columns, optionally grouped +by some other columns. A box plot is a method for graphically depicting +groups of numerical data through their quartiles. +The box extends from the Q1 to Q3 quartile values of the data, +with a line at the median (Q2). The whiskers extend from the edges +of box to show the range of the data. The position of the whiskers +is set by default to `1.5 * IQR (IQR = Q3 - Q1)` from the edges of the box. +Outlier points are those past the end of the whiskers. + +For further details see +Wikipedia's entry for `boxplot `_. + +Parameters +---------- +column : str or list of str, optional + Column name or list of names, or vector. + Can be any valid input to :meth:`pandas.DataFrame.groupby`. +by : str or array-like, optional + Column in the DataFrame to :meth:`pandas.DataFrame.groupby`. + One box-plot will be done per value of columns in `by`. +ax : object of class matplotlib.axes.Axes, optional + The matplotlib axes to be used by boxplot. +fontsize : float or str + Tick label font size in points or as a string (e.g., `large`). +rot : int or float, default 0 + The rotation angle of labels (in degrees) + with respect to the screen coordinate system. +grid : bool, default True + Setting this to True will show the grid. +figsize : A tuple (width, height) in inches + The size of the figure to create in matplotlib. +layout : tuple (rows, columns), optional + For example, (3, 5) will display the subplots + using 3 columns and 5 rows, starting from the top-left. +return_type : {'axes', 'dict', 'both'} or None, default 'axes' + The kind of object to return. The default is ``axes``. + + * 'axes' returns the matplotlib axes the boxplot is drawn on. + * 'dict' returns a dictionary whose values are the matplotlib + Lines of the boxplot. + * 'both' returns a namedtuple with the axes and dict. + * when grouping with ``by``, a Series mapping columns to + ``return_type`` is returned. + + If ``return_type`` is `None`, a NumPy array + of axes with the same shape as ``layout`` is returned. +%(backend)s\ + +**kwargs + All other plotting keyword arguments to be passed to + :func:`matplotlib.pyplot.boxplot`. + +Returns +------- +result + See Notes. + +See Also +-------- +Series.plot.hist: Make a histogram. +matplotlib.pyplot.boxplot : Matplotlib equivalent plot. + +Notes +----- +The return type depends on the `return_type` parameter: + +* 'axes' : object of class matplotlib.axes.Axes +* 'dict' : dict of matplotlib.lines.Line2D objects +* 'both' : a namedtuple with structure (ax, lines) + +For data grouped with ``by``, return a Series of the above or a numpy +array: + +* :class:`~pandas.Series` +* :class:`~numpy.array` (for ``return_type = None``) + +Use ``return_type='dict'`` when you want to tweak the appearance +of the lines after plotting. In this case a dict containing the Lines +making up the boxes, caps, fliers, medians, and whiskers is returned. + +Examples +-------- + +Boxplots can be created for every column in the dataframe +by ``df.boxplot()`` or indicating the columns to be used: + +.. plot:: + :context: close-figs + + >>> np.random.seed(1234) + >>> df = pd.DataFrame(np.random.randn(10, 4), + ... columns=['Col1', 'Col2', 'Col3', 'Col4']) + >>> boxplot = df.boxplot(column=['Col1', 'Col2', 'Col3']) + +Boxplots of variables distributions grouped by the values of a third +variable can be created using the option ``by``. For instance: + +.. plot:: + :context: close-figs + + >>> df = pd.DataFrame(np.random.randn(10, 2), + ... columns=['Col1', 'Col2']) + >>> df['X'] = pd.Series(['A', 'A', 'A', 'A', 'A', + ... 'B', 'B', 'B', 'B', 'B']) + >>> boxplot = df.boxplot(by='X') + +A list of strings (i.e. ``['X', 'Y']``) can be passed to boxplot +in order to group the data by combination of the variables in the x-axis: + +.. plot:: + :context: close-figs + + >>> df = pd.DataFrame(np.random.randn(10, 3), + ... columns=['Col1', 'Col2', 'Col3']) + >>> df['X'] = pd.Series(['A', 'A', 'A', 'A', 'A', + ... 'B', 'B', 'B', 'B', 'B']) + >>> df['Y'] = pd.Series(['A', 'B', 'A', 'B', 'A', + ... 'B', 'A', 'B', 'A', 'B']) + >>> boxplot = df.boxplot(column=['Col1', 'Col2'], by=['X', 'Y']) + +The layout of boxplot can be adjusted giving a tuple to ``layout``: + +.. plot:: + :context: close-figs + + >>> boxplot = df.boxplot(column=['Col1', 'Col2'], by='X', + ... layout=(2, 1)) - Parameters - ---------- - column : str or list of str, optional - Column name or list of names, or vector. - Can be any valid input to :meth:`pandas.DataFrame.groupby`. - by : str or array-like, optional - Column in the DataFrame to :meth:`pandas.DataFrame.groupby`. - One box-plot will be done per value of columns in `by`. - ax : object of class matplotlib.axes.Axes, optional - The matplotlib axes to be used by boxplot. - fontsize : float or str - Tick label font size in points or as a string (e.g., `large`). - rot : int or float, default 0 - The rotation angle of labels (in degrees) - with respect to the screen coordinate system. - grid : bool, default True - Setting this to True will show the grid. - figsize : A tuple (width, height) in inches - The size of the figure to create in matplotlib. - layout : tuple (rows, columns), optional - For example, (3, 5) will display the subplots - using 3 columns and 5 rows, starting from the top-left. - return_type : {'axes', 'dict', 'both'} or None, default 'axes' - The kind of object to return. The default is ``axes``. - - * 'axes' returns the matplotlib axes the boxplot is drawn on. - * 'dict' returns a dictionary whose values are the matplotlib - Lines of the boxplot. - * 'both' returns a namedtuple with the axes and dict. - * when grouping with ``by``, a Series mapping columns to - ``return_type`` is returned. - - If ``return_type`` is `None`, a NumPy array - of axes with the same shape as ``layout`` is returned. - **kwargs - All other plotting keyword arguments to be passed to - :func:`matplotlib.pyplot.boxplot`. +Additional formatting can be done to the boxplot, like suppressing the grid +(``grid=False``), rotating the labels in the x-axis (i.e. ``rot=45``) +or changing the fontsize (i.e. ``fontsize=15``): - Returns - ------- - result - See Notes. +.. plot:: + :context: close-figs - See Also - -------- - Series.plot.hist: Make a histogram. - matplotlib.pyplot.boxplot : Matplotlib equivalent plot. - - Notes - ----- - The return type depends on the `return_type` parameter: + >>> boxplot = df.boxplot(grid=False, rot=45, fontsize=15) - * 'axes' : object of class matplotlib.axes.Axes - * 'dict' : dict of matplotlib.lines.Line2D objects - * 'both' : a namedtuple with structure (ax, lines) +The parameter ``return_type`` can be used to select the type of element +returned by `boxplot`. When ``return_type='axes'`` is selected, +the matplotlib axes on which the boxplot is drawn are returned: - For data grouped with ``by``, return a Series of the above or a numpy - array: + >>> boxplot = df.boxplot(column=['Col1', 'Col2'], return_type='axes') + >>> type(boxplot) + - * :class:`~pandas.Series` - * :class:`~numpy.array` (for ``return_type = None``) +When grouping with ``by``, a Series mapping columns to ``return_type`` +is returned: - Use ``return_type='dict'`` when you want to tweak the appearance - of the lines after plotting. In this case a dict containing the Lines - making up the boxes, caps, fliers, medians, and whiskers is returned. + >>> boxplot = df.boxplot(column=['Col1', 'Col2'], by='X', + ... return_type='axes') + >>> type(boxplot) + - Examples - -------- +If ``return_type`` is `None`, a NumPy array of axes with the same shape +as ``layout`` is returned: - Boxplots can be created for every column in the dataframe - by ``df.boxplot()`` or indicating the columns to be used: + >>> boxplot = df.boxplot(column=['Col1', 'Col2'], by='X', + ... return_type=None) + >>> type(boxplot) + +""" - .. plot:: - :context: close-figs - >>> np.random.seed(1234) - >>> df = pd.DataFrame(np.random.randn(10,4), - ... columns=['Col1', 'Col2', 'Col3', 'Col4']) - >>> boxplot = df.boxplot(column=['Col1', 'Col2', 'Col3']) +_backend_doc = """\ +backend : str, default None + Backend to use instead of the backend specified in the option + ``plotting.backend``. For instance, 'matplotlib'. Alternatively, to + specify the ``plotting.backend`` for the whole session, set + ``pd.options.plotting.backend``. +""" - Boxplots of variables distributions grouped by the values of a third - variable can be created using the option ``by``. For instance: - .. plot:: - :context: close-figs - - >>> df = pd.DataFrame(np.random.randn(10, 2), - ... columns=['Col1', 'Col2']) - >>> df['X'] = pd.Series(['A', 'A', 'A', 'A', 'A', - ... 'B', 'B', 'B', 'B', 'B']) - >>> boxplot = df.boxplot(by='X') - - A list of strings (i.e. ``['X', 'Y']``) can be passed to boxplot - in order to group the data by combination of the variables in the x-axis: - - .. plot:: - :context: close-figs - - >>> df = pd.DataFrame(np.random.randn(10,3), - ... columns=['Col1', 'Col2', 'Col3']) - >>> df['X'] = pd.Series(['A', 'A', 'A', 'A', 'A', - ... 'B', 'B', 'B', 'B', 'B']) - >>> df['Y'] = pd.Series(['A', 'B', 'A', 'B', 'A', - ... 'B', 'A', 'B', 'A', 'B']) - >>> boxplot = df.boxplot(column=['Col1', 'Col2'], by=['X', 'Y']) - - The layout of boxplot can be adjusted giving a tuple to ``layout``: - - .. plot:: - :context: close-figs - - >>> boxplot = df.boxplot(column=['Col1', 'Col2'], by='X', - ... layout=(2, 1)) - - Additional formatting can be done to the boxplot, like suppressing the grid - (``grid=False``), rotating the labels in the x-axis (i.e. ``rot=45``) - or changing the fontsize (i.e. ``fontsize=15``): - - .. plot:: - :context: close-figs - - >>> boxplot = df.boxplot(grid=False, rot=45, fontsize=15) - - The parameter ``return_type`` can be used to select the type of element - returned by `boxplot`. When ``return_type='axes'`` is selected, - the matplotlib axes on which the boxplot is drawn are returned: - - >>> boxplot = df.boxplot(column=['Col1','Col2'], return_type='axes') - >>> type(boxplot) - - - When grouping with ``by``, a Series mapping columns to ``return_type`` - is returned: - - >>> boxplot = df.boxplot(column=['Col1', 'Col2'], by='X', - ... return_type='axes') - >>> type(boxplot) - - - If ``return_type`` is `None`, a NumPy array of axes with the same shape - as ``layout`` is returned: - - >>> boxplot = df.boxplot(column=['Col1', 'Col2'], by='X', - ... return_type=None) - >>> type(boxplot) - - """ +@Substitution(backend="") +@Appender(_boxplot_doc) +def boxplot( + data, + column=None, + by=None, + ax=None, + fontsize=None, + rot=0, + grid=True, + figsize=None, + layout=None, + return_type=None, + **kwargs +): plot_backend = _get_plot_backend("matplotlib") return plot_backend.boxplot( data, @@ -393,6 +410,8 @@ def boxplot( ) +@Substitution(backend=_backend_doc) +@Appender(_boxplot_doc) def boxplot_frame( self, column=None, @@ -407,173 +426,6 @@ def boxplot_frame( backend=None, **kwargs ): - """ - Make a box plot from DataFrame columns. - - Make a box-and-whisker plot from DataFrame columns, optionally grouped - by some other columns. A box plot is a method for graphically depicting - groups of numerical data through their quartiles. - The box extends from the Q1 to Q3 quartile values of the data, - with a line at the median (Q2). The whiskers extend from the edges - of box to show the range of the data. The position of the whiskers - is set by default to `1.5 * IQR (IQR = Q3 - Q1)` from the edges of the box. - Outlier points are those past the end of the whiskers. - - For further details see - Wikipedia's entry for `boxplot `_. - - Parameters - ---------- - column : str or list of str, optional - Column name or list of names, or vector. - Can be any valid input to :meth:`pandas.DataFrame.groupby`. - by : str or array-like, optional - Column in the DataFrame to :meth:`pandas.DataFrame.groupby`. - One box-plot will be done per value of columns in `by`. - ax : object of class matplotlib.axes.Axes, optional - The matplotlib axes to be used by boxplot. - fontsize : float or str - Tick label font size in points or as a string (e.g., `large`). - rot : int or float, default 0 - The rotation angle of labels (in degrees) - with respect to the screen coordinate system. - grid : bool, default True - Setting this to True will show the grid. - figsize : A tuple (width, height) in inches - The size of the figure to create in matplotlib. - layout : tuple (rows, columns), optional - For example, (3, 5) will display the subplots - using 3 columns and 5 rows, starting from the top-left. - return_type : {'axes', 'dict', 'both'} or None, default 'axes' - The kind of object to return. The default is ``axes``. - - * 'axes' returns the matplotlib axes the boxplot is drawn on. - * 'dict' returns a dictionary whose values are the matplotlib - Lines of the boxplot. - * 'both' returns a namedtuple with the axes and dict. - * when grouping with ``by``, a Series mapping columns to - ``return_type`` is returned. - - If ``return_type`` is `None`, a NumPy array - of axes with the same shape as ``layout`` is returned. - backend : str, default None - Backend to use instead of the backend specified in the option - ``plotting.backend``. For instance, 'matplotlib'. Alternatively, to - specify the ``plotting.backend`` for the whole session, set - ``pd.options.plotting.backend``. - **kwds - All other plotting keyword arguments to be passed to - :func:`matplotlib.pyplot.boxplot`. - - Returns - ------- - result - See Notes. - - See Also - -------- - Series.plot.hist: Make a histogram. - matplotlib.pyplot.boxplot : Matplotlib equivalent plot. - - Notes - ----- - The return type depends on the `return_type` parameter: - - * 'axes' : object of class matplotlib.axes.Axes - * 'dict' : dict of matplotlib.lines.Line2D objects - * 'both' : a namedtuple with structure (ax, lines) - - For data grouped with ``by``, return a Series of the above or a numpy - array: - - * :class:`~pandas.Series` - * :class:`~numpy.array` (for ``return_type = None``) - - Use ``return_type='dict'`` when you want to tweak the appearance - of the lines after plotting. In this case a dict containing the Lines - making up the boxes, caps, fliers, medians, and whiskers is returned. - - Examples - -------- - - Boxplots can be created for every column in the dataframe - by ``df.boxplot()`` or indicating the columns to be used: - - .. plot:: - :context: close-figs - - >>> np.random.seed(1234) - >>> df = pd.DataFrame(np.random.randn(10,4), - ... columns=['Col1', 'Col2', 'Col3', 'Col4']) - >>> boxplot = df.boxplot(column=['Col1', 'Col2', 'Col3']) - - Boxplots of variables distributions grouped by the values of a third - variable can be created using the option ``by``. For instance: - - .. plot:: - :context: close-figs - - >>> df = pd.DataFrame(np.random.randn(10, 2), - ... columns=['Col1', 'Col2']) - >>> df['X'] = pd.Series(['A', 'A', 'A', 'A', 'A', - ... 'B', 'B', 'B', 'B', 'B']) - >>> boxplot = df.boxplot(by='X') - - A list of strings (i.e. ``['X', 'Y']``) can be passed to boxplot - in order to group the data by combination of the variables in the x-axis: - - .. plot:: - :context: close-figs - - >>> df = pd.DataFrame(np.random.randn(10,3), - ... columns=['Col1', 'Col2', 'Col3']) - >>> df['X'] = pd.Series(['A', 'A', 'A', 'A', 'A', - ... 'B', 'B', 'B', 'B', 'B']) - >>> df['Y'] = pd.Series(['A', 'B', 'A', 'B', 'A', - ... 'B', 'A', 'B', 'A', 'B']) - >>> boxplot = df.boxplot(column=['Col1', 'Col2'], by=['X', 'Y']) - - The layout of boxplot can be adjusted giving a tuple to ``layout``: - - .. plot:: - :context: close-figs - - >>> boxplot = df.boxplot(column=['Col1', 'Col2'], by='X', - ... layout=(2, 1)) - - Additional formatting can be done to the boxplot, like suppressing the grid - (``grid=False``), rotating the labels in the x-axis (i.e. ``rot=45``) - or changing the fontsize (i.e. ``fontsize=15``): - - .. plot:: - :context: close-figs - - >>> boxplot = df.boxplot(grid=False, rot=45, fontsize=15) - - The parameter ``return_type`` can be used to select the type of element - returned by `boxplot`. When ``return_type='axes'`` is selected, - the matplotlib axes on which the boxplot is drawn are returned: - - >>> boxplot = df.boxplot(column=['Col1','Col2'], return_type='axes') - >>> type(boxplot) - - - When grouping with ``by``, a Series mapping columns to ``return_type`` - is returned: - - >>> boxplot = df.boxplot(column=['Col1', 'Col2'], by='X', - ... return_type='axes') - >>> type(boxplot) - - - If ``return_type`` is `None`, a NumPy array of axes with the same shape - as ``layout`` is returned: - - >>> boxplot = df.boxplot(column=['Col1', 'Col2'], by='X', - ... return_type=None) - >>> type(boxplot) - - """ plot_backend = _get_plot_backend(backend) return plot_backend.boxplot_frame( self, From e62e173690e42fa2f02db8537c1e65c6da0b4c95 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Tue, 5 Nov 2019 10:34:32 -0500 Subject: [PATCH 11/11] versionadded --- pandas/plotting/_core.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py index f663dec456eb6..6fc5b03920cba 100644 --- a/pandas/plotting/_core.py +++ b/pandas/plotting/_core.py @@ -56,6 +56,9 @@ def hist_series( ``plotting.backend``. For instance, 'matplotlib'. Alternatively, to specify the ``plotting.backend`` for the whole session, set ``pd.options.plotting.backend``. + + .. versionadded:: 1.0.0 + **kwargs To be passed to the actual plotting function. @@ -157,6 +160,9 @@ def hist_frame( ``plotting.backend``. For instance, 'matplotlib'. Alternatively, to specify the ``plotting.backend`` for the whole session, set ``pd.options.plotting.backend``. + + .. versionadded:: 1.0.0 + **kwargs All other plotting keyword arguments to be passed to :meth:`matplotlib.pyplot.hist`. @@ -376,6 +382,8 @@ def hist_frame( ``plotting.backend``. For instance, 'matplotlib'. Alternatively, to specify the ``plotting.backend`` for the whole session, set ``pd.options.plotting.backend``. + + .. versionadded:: 1.0.0 """ @@ -489,6 +497,9 @@ def boxplot_frame_groupby( ``plotting.backend``. For instance, 'matplotlib'. Alternatively, to specify the ``plotting.backend`` for the whole session, set ``pd.options.plotting.backend``. + + .. versionadded:: 1.0.0 + **kwargs All other plotting keyword arguments to be passed to matplotlib's boxplot function. @@ -626,6 +637,9 @@ class PlotAccessor(PandasObject): ``plotting.backend``. For instance, 'matplotlib'. Alternatively, to specify the ``plotting.backend`` for the whole session, set ``pd.options.plotting.backend``. + + .. versionadded:: 1.0.0 + **kwargs Options to pass to matplotlib plotting method.