From 00701c7a02f94be4627647e598fbe5441d465d06 Mon Sep 17 00:00:00 2001 From: Nicholas Musolino Date: Thu, 25 Oct 2018 22:26:14 -0400 Subject: [PATCH 01/15] Add Styler.pipe() method, akin to DataFrame.pipe() --- doc/source/api.rst | 1 + pandas/io/formats/style.py | 29 +++++++++++++++++++++++++++ pandas/tests/io/formats/test_style.py | 19 ++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/doc/source/api.rst b/doc/source/api.rst index 1ec2a56dcd094..0d27ef16b3e71 100644 --- a/doc/source/api.rst +++ b/doc/source/api.rst @@ -2410,6 +2410,7 @@ Style Application Styler.set_properties Styler.set_uuid Styler.clear + Styler.pipe Builtin Styles ~~~~~~~~~~~~~~ diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 3b3238586b310..8c43487596897 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -1222,6 +1222,35 @@ class MyStyler(cls): return MyStyler + def pipe(self, func, *args, **kwargs): + """ + Apply func(self, *args, **kwargs) + + Parameters + ---------- + func : function + function to apply to the Styler. + ``args``, and ``kwargs`` are passed into ``func``. + Alternatively a ``(callable, data_keyword)`` tuple where + ``data_keyword`` is a string indicating the keyword of + ``callable`` that expects the Styler. + args : iterable, optional + positional arguments passed into ``func``. + kwargs : mapping, optional + a dictionary of keyword arguments passed into ``func``. + + Returns + ------- + result : the value returned by ``func``. + + See Also + -------- + Styler.apply + Styler.applymap + pandas.DataFrame.pipe + """ + return com._pipe(self, func, *args, **kwargs) + def _is_visible(idx_row, idx_col, lengths): """ diff --git a/pandas/tests/io/formats/test_style.py b/pandas/tests/io/formats/test_style.py index e407573c9a462..1c5cbc172a8f0 100644 --- a/pandas/tests/io/formats/test_style.py +++ b/pandas/tests/io/formats/test_style.py @@ -1173,6 +1173,25 @@ def test_hide_columns_mult_levels(self): assert ctx['body'][1][2]['is_visible'] assert ctx['body'][1][2]['display_value'] == 3 + def test_pipe(self): + def set_caption_from_template(styler, a, b): + return styler.set_caption( + 'Dataframe with a = {a} and b = {b}'.format(a=a, b=b)) + styler = self.df.style.pipe(set_caption_from_template, 'A', b='B') + assert 'Dataframe with a = A and b = B' in styler.render() + + def f(s, *args, **kwargs): + return s, args, kwargs + + result = self.df.style.pipe(f, 0, a=1) + assert result[1] == (0,) + assert result[2] == dict(a=1) + + def g(**kwargs): + assert 'styler' in kwargs + return kwargs['styler'].data + assert self.df.style.pipe((g, 'styler')) is self.df + @td.skip_if_no_mpl class TestStylerMatplotlibDep(object): From c6a92cd605aebbea410189e7acd5a718ecfe309b Mon Sep 17 00:00:00 2001 From: Nicholas Musolino Date: Sat, 27 Oct 2018 16:48:40 -0400 Subject: [PATCH 02/15] Add whatsnew entry for `Styler.pipe()` --- doc/source/whatsnew/v0.24.0.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index 47fef83d3015d..e63fa91400d18 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -214,6 +214,7 @@ Other Enhancements - Compatibility with Matplotlib 3.0 (:issue:`22790`). - Added :meth:`Interval.overlaps`, :meth:`IntervalArray.overlaps`, and :meth:`IntervalIndex.overlaps` for determining overlaps between interval-like objects (:issue:`21998`) - :meth:`Timestamp.tz_localize`, :meth:`DatetimeIndex.tz_localize`, and :meth:`Series.tz_localize` have gained the ``nonexistent`` argument for alternative handling of nonexistent times. See :ref:`timeseries.timezone_nonexsistent` (:issue:`8917`) +- :meth:`Styler.pipe` method added, to simplify application of user-defined functions that operate on stylers. .. _whatsnew_0240.api_breaking: From 36606ee93eaba4e801dd1456070e3bd16694cea7 Mon Sep 17 00:00:00 2001 From: Nicholas Musolino Date: Sat, 27 Oct 2018 20:24:37 -0400 Subject: [PATCH 03/15] Simplify Styler.pipe() unit tests --- pandas/tests/io/formats/test_style.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/pandas/tests/io/formats/test_style.py b/pandas/tests/io/formats/test_style.py index 1c5cbc172a8f0..9a668a1d83fa2 100644 --- a/pandas/tests/io/formats/test_style.py +++ b/pandas/tests/io/formats/test_style.py @@ -1177,20 +1177,17 @@ def test_pipe(self): def set_caption_from_template(styler, a, b): return styler.set_caption( 'Dataframe with a = {a} and b = {b}'.format(a=a, b=b)) + styler = self.df.style.pipe(set_caption_from_template, 'A', b='B') assert 'Dataframe with a = A and b = B' in styler.render() - def f(s, *args, **kwargs): - return s, args, kwargs - - result = self.df.style.pipe(f, 0, a=1) - assert result[1] == (0,) - assert result[2] == dict(a=1) + # Test with an argument that is a (callable, keyword_name) pair. + def f(a, b, styler): + return (a, b, styler) - def g(**kwargs): - assert 'styler' in kwargs - return kwargs['styler'].data - assert self.df.style.pipe((g, 'styler')) is self.df + styler = self.df.style + result = styler.pipe((f, 'styler'), a=1, b=2) + assert result == (1, 2, styler) @td.skip_if_no_mpl From 73821baafc916db1c7ef60d1c20f2a345a2cd0b4 Mon Sep 17 00:00:00 2001 From: Nicholas Musolino Date: Sat, 27 Oct 2018 22:08:19 -0400 Subject: [PATCH 04/15] Styler.pipe() docstring improvements --- pandas/io/formats/style.py | 45 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 8c43487596897..3730954239892 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -1224,7 +1224,9 @@ class MyStyler(cls): def pipe(self, func, *args, **kwargs): """ - Apply func(self, *args, **kwargs) + Apply func(self, \*args, \*\*kwargs), and return the result. + + .. versionadded:: 0.24.0 Parameters ---------- @@ -1241,13 +1243,52 @@ def pipe(self, func, *args, **kwargs): Returns ------- - result : the value returned by ``func``. + object : the value returned by ``func``. See Also -------- Styler.apply Styler.applymap pandas.DataFrame.pipe + + Notes + ----- + Like :meth:`pandas.DataFrame.pipe`, this method can simplify the + application of several user-defined functions to a styler. Instead + of writing: + + >>> f(g(df.style.set_precision(3), arg1=a), arg2=b, arg3=c) + + users can write: + + >>> df.style.set_precision(3) + ... .pipe(g, arg1=a) + ... .pipe(f, arg2=b, arg3=c) + + In particular, this allows users to define functions that take a + styler object, along with other parameters, and return the styler after + making styling changes (such as calling :meth:`Styler.apply` or + :meth:`Styler.set_properties`). Using ``.pipe``, these user-defined + style "transformations" can be interleaved with calls to the built-in + Styler interface. + + Examples + -------- + >>> def highlight_with_containing_row(styler, row_label, column): + ... ''' Highlight the indicated element, and its containing row. ''' + ... cell, row = pd.IndexSlice[row_label, column], pd.IndexSlice[row_label, :] + ... return (styler.set_properties(cell, **{'background-color': '#ffffcc'}) + ... .set_properties(row, **{'background-color': '#ffccc0'})) + + The user-defined highlight function above can be called within a + sequence of other style modifications: + + >>> df = pd.DataFrame({'A': list(range(-1, 4)), 'X': np.arange(0.2, 1.2, 0.2)}) + >>> (df.style + ... .format({'X': '{:.2%}'}) + ... .pipe(highlight_with_containing_row, 0, 'A') + ... .pipe(highlight_with_containing_row, 9, 'X') + ... .set_caption("Results with anomolous observations highlighted.") """ return com._pipe(self, func, *args, **kwargs) From df6fb422a9f968d8522aca5ab9cf7c7181ed79d7 Mon Sep 17 00:00:00 2001 From: Nicholas Musolino Date: Sat, 27 Oct 2018 22:36:42 -0400 Subject: [PATCH 05/15] Expand whatsnew entry per review feedback --- doc/source/whatsnew/v0.24.0.txt | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index e63fa91400d18..2cc9771bdee85 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -180,6 +180,26 @@ array, but rather an ``ExtensionArray``: This is the same behavior as ``Series.values`` for categorical data. See :ref:`whatsnew_0240.api_breaking.interval_values` for more. +New ``Styler.pipe()`` method +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +A new method :meth:`pandas.formats.style.Styler.pipe()` was added (:issue:`#23229`). +This provides a convenient way to apply users' predefined styling functions, and can +help reduce "boilerplate" when using DataFrame styling functionality repeatedly within +a notebook. + +.. code-block:: ipython + + def set_summary_style(styler): + return (styler.format({'N': '{:,}', 'X': '{:.1%}'}) + .set_properties(**{'text-align': 'right'})) + + (df.style.set_precision(1) + .pipe(set_summary_style) + .set_caption('Summary of results.')) + +Other classes that provide a ``pipe()`` method include DataFrame, Series, Groupby, +and Resampler. + .. _whatsnew_0240.enhancements.other: Other Enhancements @@ -214,7 +234,6 @@ Other Enhancements - Compatibility with Matplotlib 3.0 (:issue:`22790`). - Added :meth:`Interval.overlaps`, :meth:`IntervalArray.overlaps`, and :meth:`IntervalIndex.overlaps` for determining overlaps between interval-like objects (:issue:`21998`) - :meth:`Timestamp.tz_localize`, :meth:`DatetimeIndex.tz_localize`, and :meth:`Series.tz_localize` have gained the ``nonexistent`` argument for alternative handling of nonexistent times. See :ref:`timeseries.timezone_nonexsistent` (:issue:`8917`) -- :meth:`Styler.pipe` method added, to simplify application of user-defined functions that operate on stylers. .. _whatsnew_0240.api_breaking: From e5eacbe2c12e71b96d63959bb0535bca74fe564d Mon Sep 17 00:00:00 2001 From: Nicholas Musolino Date: Mon, 29 Oct 2018 21:39:52 -0400 Subject: [PATCH 06/15] Revise whatsnew message --- doc/source/whatsnew/v0.24.0.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index 2cc9771bdee85..d1096a3a596fc 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -182,9 +182,9 @@ This is the same behavior as ``Series.values`` for categorical data. See New ``Styler.pipe()`` method ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A new method :meth:`pandas.formats.style.Styler.pipe()` was added (:issue:`#23229`). -This provides a convenient way to apply users' predefined styling functions, and can -help reduce "boilerplate" when using DataFrame styling functionality repeatedly within +The dataframe Styler class has gained a :meth:`~pandas.io.formats.style.Styler.pipe` method +(:issue:`23229`). This provides a convenient way to apply users' predefined styling functions, +and can help reduce "boilerplate" when using DataFrame styling functionality repeatedly within a notebook. .. code-block:: ipython @@ -197,8 +197,9 @@ a notebook. .pipe(set_summary_style) .set_caption('Summary of results.')) -Other classes that provide a ``pipe()`` method include DataFrame, Series, Groupby, -and Resampler. +Similar methods already exist for other classes in pandas, including :meth:`DataFrame.pipe`, +:meth:`Groupby.pipe`, and :meth:`Resampler.pipe`. + .. _whatsnew_0240.enhancements.other: From 51b21ac65937560abdc5f6b2c55d8cd4ee27d05d Mon Sep 17 00:00:00 2001 From: Nicholas Musolino Date: Mon, 29 Oct 2018 22:02:31 -0400 Subject: [PATCH 07/15] Improve Styler.pipe() docstring --- pandas/io/formats/style.py | 44 ++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 3730954239892..543365300ea50 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -1224,32 +1224,33 @@ class MyStyler(cls): def pipe(self, func, *args, **kwargs): """ - Apply func(self, \*args, \*\*kwargs), and return the result. + Apply ``func(self, \*args, \*\*kwargs)``, and return the result. .. versionadded:: 0.24.0 Parameters ---------- func : function - function to apply to the Styler. - ``args``, and ``kwargs`` are passed into ``func``. + Function to apply to the Styler. + ``*args``, and ``**kwargs`` are passed into ``func``. Alternatively a ``(callable, data_keyword)`` tuple where ``data_keyword`` is a string indicating the keyword of ``callable`` that expects the Styler. - args : iterable, optional - positional arguments passed into ``func``. - kwargs : mapping, optional - a dictionary of keyword arguments passed into ``func``. + *args : iterable, optional + Positional arguments passed into ``func``. + **kwargs : dict, optional + Dictionary of keyword arguments passed into ``func``. Returns ------- - object : the value returned by ``func``. + result : object + The value returned by ``func``. See Also -------- - Styler.apply - Styler.applymap - pandas.DataFrame.pipe + DataFrame.pipe : Analogous method for DataFrame. + Styler.apply : Apply a function row-wise, column-wise, or table-wise to + modify the dataframe's styling. Notes ----- @@ -1261,9 +1262,9 @@ def pipe(self, func, *args, **kwargs): users can write: - >>> df.style.set_precision(3) - ... .pipe(g, arg1=a) - ... .pipe(f, arg2=b, arg3=c) + >>> (df.style.set_precision(3) + ... .pipe(g, arg1=a) + ... .pipe(f, arg2=b, arg3=c)) In particular, this allows users to define functions that take a styler object, along with other parameters, and return the styler after @@ -1274,21 +1275,18 @@ def pipe(self, func, *args, **kwargs): Examples -------- - >>> def highlight_with_containing_row(styler, row_label, column): - ... ''' Highlight the indicated element, and its containing row. ''' - ... cell, row = pd.IndexSlice[row_label, column], pd.IndexSlice[row_label, :] - ... return (styler.set_properties(cell, **{'background-color': '#ffffcc'}) - ... .set_properties(row, **{'background-color': '#ffccc0'})) + >>> def set_standard_formatting(styler): + ... return (styler.set_properties(**{'text-align': 'right'}) + ... .format({'X': '{:.1%}'})) The user-defined highlight function above can be called within a sequence of other style modifications: >>> df = pd.DataFrame({'A': list(range(-1, 4)), 'X': np.arange(0.2, 1.2, 0.2)}) >>> (df.style - ... .format({'X': '{:.2%}'}) - ... .pipe(highlight_with_containing_row, 0, 'A') - ... .pipe(highlight_with_containing_row, 9, 'X') - ... .set_caption("Results with anomolous observations highlighted.") + ... .set_properties(subset=['X'], **{'background-color': 'yellow'}) + ... .pipe(set_standard_formatting) + ... .set_caption("Results with column 'X' highlighted.")) """ return com._pipe(self, func, *args, **kwargs) From a0e758e4b9dd50bb7e0bee057076036fa60e8d23 Mon Sep 17 00:00:00 2001 From: Nicholas Musolino Date: Mon, 29 Oct 2018 22:27:43 -0400 Subject: [PATCH 08/15] Final docstring tweak --- pandas/io/formats/style.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 543365300ea50..150f018fea1b9 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -1224,7 +1224,7 @@ class MyStyler(cls): def pipe(self, func, *args, **kwargs): """ - Apply ``func(self, \*args, \*\*kwargs)``, and return the result. + Apply ``func(self, *args, **kwargs)``, and return the result. .. versionadded:: 0.24.0 @@ -1254,7 +1254,7 @@ def pipe(self, func, *args, **kwargs): Notes ----- - Like :meth:`pandas.DataFrame.pipe`, this method can simplify the + Like :meth:`DataFrame.pipe`, this method can simplify the application of several user-defined functions to a styler. Instead of writing: From 21403f721b65e23faa4c3d0a7379ab74e54c58cb Mon Sep 17 00:00:00 2001 From: Nicholas Musolino Date: Mon, 5 Nov 2018 21:31:18 -0500 Subject: [PATCH 09/15] More whatsnew revisions --- doc/source/whatsnew/v0.24.0.txt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index d1096a3a596fc..e5388fef69436 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -180,14 +180,18 @@ array, but rather an ``ExtensionArray``: This is the same behavior as ``Series.values`` for categorical data. See :ref:`whatsnew_0240.api_breaking.interval_values` for more. + +.. _whatsnew_0240.enhancements.styler_pipe: + New ``Styler.pipe()`` method ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The dataframe Styler class has gained a :meth:`~pandas.io.formats.style.Styler.pipe` method -(:issue:`23229`). This provides a convenient way to apply users' predefined styling functions, -and can help reduce "boilerplate" when using DataFrame styling functionality repeatedly within +The :class:`~pandas.io.formats.style.Styler` class has gained a +:meth:`~pandas.io.formats.style.Styler.pipe` method (:issue:`23229`). This provides a +convenient way to apply users' predefined styling functions, and can help reduce +"boilerplate" when using DataFrame styling functionality repeatedly within a notebook. -.. code-block:: ipython +.. ipython:: python def set_summary_style(styler): return (styler.format({'N': '{:,}', 'X': '{:.1%}'}) From 0363ea89cc7f9bb96a74e6f2cca7304a56e40d66 Mon Sep 17 00:00:00 2001 From: Nicholas Musolino Date: Mon, 5 Nov 2018 21:39:22 -0500 Subject: [PATCH 10/15] Change non-runnable doctests to code blocks --- pandas/io/formats/style.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 150f018fea1b9..2a8b953b8a15c 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -1258,13 +1258,17 @@ def pipe(self, func, *args, **kwargs): application of several user-defined functions to a styler. Instead of writing: - >>> f(g(df.style.set_precision(3), arg1=a), arg2=b, arg3=c) + .. code-block:: python + + f(g(df.style.set_precision(3), arg1=a), arg2=b, arg3=c) users can write: - >>> (df.style.set_precision(3) - ... .pipe(g, arg1=a) - ... .pipe(f, arg2=b, arg3=c)) + .. code-block:: python + + (df.style.set_precision(3) + .pipe(g, arg1=a) + .pipe(f, arg2=b, arg3=c)) In particular, this allows users to define functions that take a styler object, along with other parameters, and return the styler after From 0798c73d18693743229b16e18ae9f2da5c339481 Mon Sep 17 00:00:00 2001 From: Nicholas Musolino Date: Sat, 10 Nov 2018 11:23:50 -0500 Subject: [PATCH 11/15] Simplify docstring parameters/return sections --- pandas/io/formats/style.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 2a8b953b8a15c..748b7ab71f6ec 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -1231,19 +1231,15 @@ def pipe(self, func, *args, **kwargs): Parameters ---------- func : function - Function to apply to the Styler. - ``*args``, and ``**kwargs`` are passed into ``func``. - Alternatively a ``(callable, data_keyword)`` tuple where - ``data_keyword`` is a string indicating the keyword of - ``callable`` that expects the Styler. - *args : iterable, optional - Positional arguments passed into ``func``. - **kwargs : dict, optional - Dictionary of keyword arguments passed into ``func``. + Function to apply to the Styler. Alternatively, a + ``(callable, keyword)`` tuple where ``keyword`` is a string + indicating the keyword of ``callable`` that expects the Styler. + *args, **kwargs : + Arguments passed to `func`. Returns ------- - result : object + object : The value returned by ``func``. See Also From 7cbb6b0959dfa7bc5d403a7cc8da1d6d3a8ddb9e Mon Sep 17 00:00:00 2001 From: Nicholas Musolino Date: Sat, 10 Nov 2018 11:40:03 -0500 Subject: [PATCH 12/15] Modify doctest example --- pandas/io/formats/style.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 748b7ab71f6ec..620d91a09ffd4 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -1275,18 +1275,18 @@ def pipe(self, func, *args, **kwargs): Examples -------- - >>> def set_standard_formatting(styler): + >>> def format_conversion(styler): ... return (styler.set_properties(**{'text-align': 'right'}) - ... .format({'X': '{:.1%}'})) + ... .format({'conversion': '{:.1%}'})) - The user-defined highlight function above can be called within a + The user-defined `format_conversion` function above can be called within a sequence of other style modifications: - >>> df = pd.DataFrame({'A': list(range(-1, 4)), 'X': np.arange(0.2, 1.2, 0.2)}) + >>> df = pd.DataFrame({'trial': list(range(5)), 'conversion': [0.75, 0.85, np.nan, 0.70, 0.725]}) >>> (df.style - ... .set_properties(subset=['X'], **{'background-color': 'yellow'}) - ... .pipe(set_standard_formatting) - ... .set_caption("Results with column 'X' highlighted.")) + ... .highlight_min(color='yellow') + ... .pipe(format_conversion) + ... .set_caption("Experiment results, with minimum conversion highlighted.")) """ return com._pipe(self, func, *args, **kwargs) From ae83236a9686d64d6384b8cf253e24321f9173bf Mon Sep 17 00:00:00 2001 From: Nicholas Musolino Date: Sat, 10 Nov 2018 11:53:59 -0500 Subject: [PATCH 13/15] Use natural subset for doctest example --- pandas/io/formats/style.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 620d91a09ffd4..7dc642b4c4341 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -1284,7 +1284,7 @@ def pipe(self, func, *args, **kwargs): >>> df = pd.DataFrame({'trial': list(range(5)), 'conversion': [0.75, 0.85, np.nan, 0.70, 0.725]}) >>> (df.style - ... .highlight_min(color='yellow') + ... .highlight_min(subset=['conversion'], color='yellow') ... .pipe(format_conversion) ... .set_caption("Experiment results, with minimum conversion highlighted.")) """ From 706f3a6d217da8ca96493c66616dbcfdc96e7920 Mon Sep 17 00:00:00 2001 From: Nicholas Musolino Date: Sat, 17 Nov 2018 20:41:44 -0500 Subject: [PATCH 14/15] Ensure whatsnew entry runs cleanly --- doc/source/whatsnew/v0.24.0.txt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index d6eb060089d60..b536f469fcc33 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -187,18 +187,17 @@ New ``Styler.pipe()`` method The :class:`~pandas.io.formats.style.Styler` class has gained a :meth:`~pandas.io.formats.style.Styler.pipe` method (:issue:`23229`). This provides a convenient way to apply users' predefined styling functions, and can help reduce -"boilerplate" when using DataFrame styling functionality repeatedly within -a notebook. +"boilerplate" when using DataFrame styling functionality repeatedly within a notebook. .. ipython:: python - def set_summary_style(styler): + df = pandas.DataFrame({'N': [1250, 1500, 1750], 'X': [0.25, 0.35, 0.50]}) + + def format_and_align(styler): return (styler.format({'N': '{:,}', 'X': '{:.1%}'}) .set_properties(**{'text-align': 'right'})) - (df.style.set_precision(1) - .pipe(set_summary_style) - .set_caption('Summary of results.')) + df.style.pipe(format_and_align).set_caption('Summary of results.') Similar methods already exist for other classes in pandas, including :meth:`DataFrame.pipe`, :meth:`Groupby.pipe`, and :meth:`Resampler.pipe`. From 28d7098d4a36c8bafe094e903fc57059257d3f59 Mon Sep 17 00:00:00 2001 From: Nicholas Musolino Date: Sat, 17 Nov 2018 20:45:22 -0500 Subject: [PATCH 15/15] Fix docstring line length, format issues --- pandas/io/formats/style.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index 7dc642b4c4341..ba32c315d5768 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -1279,14 +1279,15 @@ def pipe(self, func, *args, **kwargs): ... return (styler.set_properties(**{'text-align': 'right'}) ... .format({'conversion': '{:.1%}'})) - The user-defined `format_conversion` function above can be called within a - sequence of other style modifications: + The user-defined ``format_conversion`` function above can be called + within a sequence of other style modifications: - >>> df = pd.DataFrame({'trial': list(range(5)), 'conversion': [0.75, 0.85, np.nan, 0.70, 0.725]}) + >>> df = pd.DataFrame({'trial': list(range(5)), + ... 'conversion': [0.75, 0.85, np.nan, 0.7, 0.72]}) >>> (df.style ... .highlight_min(subset=['conversion'], color='yellow') ... .pipe(format_conversion) - ... .set_caption("Experiment results, with minimum conversion highlighted.")) + ... .set_caption("Results with minimum conversion highlighted.")) """ return com._pipe(self, func, *args, **kwargs)