Skip to content

Commit 82b6175

Browse files
authored
DOC: examples for Styler.pipe (#45880)
1 parent 1b45448 commit 82b6175

File tree

5 files changed

+64
-20
lines changed

5 files changed

+64
-20
lines changed
5.84 KB
Loading
5.67 KB
Loading
5.36 KB
Loading
6.28 KB
Loading

pandas/io/formats/style.py

+64-20
Original file line numberDiff line numberDiff line change
@@ -3509,41 +3509,85 @@ def pipe(self, func: Callable, *args, **kwargs):
35093509
35103510
.. code-block:: python
35113511
3512-
f(g(df.style.set_precision(3), arg1=a), arg2=b, arg3=c)
3512+
f(g(df.style.format(precision=3), arg1=a), arg2=b, arg3=c)
35133513
35143514
users can write:
35153515
35163516
.. code-block:: python
35173517
3518-
(df.style.set_precision(3)
3518+
(df.style.format(precision=3)
35193519
.pipe(g, arg1=a)
35203520
.pipe(f, arg2=b, arg3=c))
35213521
35223522
In particular, this allows users to define functions that take a
35233523
styler object, along with other parameters, and return the styler after
35243524
making styling changes (such as calling :meth:`Styler.apply` or
3525-
:meth:`Styler.set_properties`). Using ``.pipe``, these user-defined
3526-
style "transformations" can be interleaved with calls to the built-in
3527-
Styler interface.
3525+
:meth:`Styler.set_properties`).
35283526
35293527
Examples
35303528
--------
3531-
>>> def format_conversion(styler):
3532-
... return (styler.set_properties(**{'text-align': 'right'})
3533-
... .format({'conversion': '{:.1%}'}))
3534-
3535-
The user-defined ``format_conversion`` function above can be called
3536-
within a sequence of other style modifications:
3537-
3538-
>>> df = pd.DataFrame({'trial': list(range(5)),
3539-
... 'conversion': [0.75, 0.85, np.nan, 0.7, 0.72]})
3540-
>>> (df.style
3541-
... .highlight_min(subset=['conversion'], color='yellow')
3542-
... .pipe(format_conversion)
3543-
... .set_caption("Results with minimum conversion highlighted."))
3544-
... # doctest: +SKIP
35453529
3546-
.. figure:: ../../_static/style/df_pipe.png
3530+
**Common Use**
3531+
3532+
A common usage pattern is to pre-define styling operations which
3533+
can be easily applied to a generic styler in a single ``pipe`` call.
3534+
3535+
>>> def some_highlights(styler, min_color="red", max_color="blue"):
3536+
... styler.highlight_min(color=min_color, axis=None)
3537+
... styler.highlight_max(color=max_color, axis=None)
3538+
... styler.highlight_null()
3539+
... return styler
3540+
>>> df = pd.DataFrame([[1, 2, 3, pd.NA], [pd.NA, 4, 5, 6]], dtype="Int64")
3541+
>>> df.style.pipe(some_highlights, min_color="green") # doctest: +SKIP
3542+
3543+
.. figure:: ../../_static/style/df_pipe_hl.png
3544+
3545+
Since the method returns a ``Styler`` object it can be chained with other
3546+
methods as if applying the underlying highlighters directly.
3547+
3548+
>>> df.style.format("{:.1f}")
3549+
... .pipe(some_highlights, min_color="green")
3550+
... .highlight_between(left=2, right=5) # doctest: +SKIP
3551+
3552+
.. figure:: ../../_static/style/df_pipe_hl2.png
3553+
3554+
**Advanced Use**
3555+
3556+
Sometimes it may be necessary to pre-define styling functions, but in the case
3557+
where those functions rely on the styler, data or context. Since
3558+
``Styler.use`` and ``Styler.export`` are designed to be non-data dependent,
3559+
they cannot be used for this purpose. Additionally the ``Styler.apply``
3560+
and ``Styler.format`` type methods are not context aware, so a solution
3561+
is to use ``pipe`` to dynamically wrap this functionality.
3562+
3563+
Suppose we want to code a generic styling function that highlights the final
3564+
level of a MultiIndex. The number of levels in the Index is dynamic so we
3565+
need the ``Styler`` context to define the level.
3566+
3567+
>>> def highlight_last_level(styler):
3568+
... return styler.apply_index(
3569+
... lambda v: "background-color: pink; color: yellow", axis="columns",
3570+
... level=styler.columns.nlevels-1
3571+
... ) # doctest: +SKIP
3572+
>>> df.columns = pd.MultiIndex.from_product([["A", "B"], ["X", "Y"]])
3573+
>>> df.style.pipe(highlight_last_level) # doctest: +SKIP
3574+
3575+
.. figure:: ../../_static/style/df_pipe_applymap.png
3576+
3577+
Additionally suppose we want to highlight a column header if there is any
3578+
missing data in that column.
3579+
In this case we need the data object itself to determine the effect on the
3580+
column headers.
3581+
3582+
>>> def highlight_header_missing(styler, level):
3583+
... def dynamic_highlight(s):
3584+
... return np.where(
3585+
... styler.data.isna().any(), "background-color: red;", ""
3586+
... )
3587+
... return styler.apply_index(dynamic_highlight, axis=1, level=level)
3588+
>>> df.style.pipe(highlight_header_missing, level=1) # doctest: +SKIP
3589+
3590+
.. figure:: ../../_static/style/df_pipe_applydata.png
35473591
"""
35483592
return com.pipe(self, func, *args, **kwargs)
35493593

0 commit comments

Comments
 (0)