Skip to content

ENH: Styler.to_string #44502

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 66 commits into from
Jan 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
e03e014
build format_index mechanics
attack68 Aug 16, 2021
bb9b5b2
Merge remote-tracking branch 'upstream/master' into styler_format_index
attack68 Aug 17, 2021
fb86279
test index formatter display_value, and clearing
attack68 Aug 17, 2021
846e5a2
prelim doc string
attack68 Aug 17, 2021
7e9400a
format_index docs
attack68 Aug 18, 2021
9c63ab8
Merge remote-tracking branch 'upstream/master' into styler_format_index
attack68 Aug 19, 2021
87a6c88
refactor for perf
attack68 Aug 19, 2021
9c969ad
add test
attack68 Aug 20, 2021
26f3906
add tests: escape
attack68 Aug 21, 2021
ec40418
add tests: escape na_rep
attack68 Aug 21, 2021
0de5397
add tests: raises
attack68 Aug 21, 2021
6fe8285
test decimal and thousands
attack68 Aug 21, 2021
6b61e31
test precision
attack68 Aug 21, 2021
6eaa933
Merge remote-tracking branch 'upstream/master' into styler_format_index
attack68 Aug 30, 2021
666e460
whats new
attack68 Aug 30, 2021
49bb731
level tests
attack68 Aug 30, 2021
044cd05
user guide
attack68 Aug 30, 2021
8fc497d
typing fix
attack68 Aug 31, 2021
8fb9519
user guide refactor
attack68 Aug 31, 2021
d039105
Merge remote-tracking branch 'upstream/master' into styler_format_index
attack68 Sep 1, 2021
df7548c
input to axis
attack68 Sep 1, 2021
0d91aff
Merge remote-tracking branch 'upstream/master' into styler_format_index
attack68 Sep 2, 2021
e36f198
fix tests
attack68 Sep 2, 2021
b87ef09
Merge remote-tracking branch 'upstream/master' into styler_format_index
attack68 Sep 4, 2021
9a7a8e4
Merge remote-tracking branch 'upstream/master' into styler_format_index
attack68 Sep 5, 2021
ecd01dd
fix recent merged tests
attack68 Sep 5, 2021
1a32d17
Merge remote-tracking branch 'upstream/master' into styler_format_index
attack68 Sep 7, 2021
4ccf831
pandas to_string
attack68 Sep 7, 2021
afa6da3
Merge remote-tracking branch 'upstream/master' into styler_format_index
attack68 Sep 8, 2021
7e6bf97
Merge remote-tracking branch 'upstream/master' into styler_format_index
attack68 Sep 8, 2021
06ce6bf
add to style.rst
attack68 Sep 8, 2021
6ab8c24
Merge branch 'styler_format_index' into styler_to_string
attack68 Sep 8, 2021
8312e30
add justification of strings
attack68 Sep 8, 2021
5924dca
bug fix
attack68 Sep 8, 2021
739a4a0
test and whats new
attack68 Sep 8, 2021
8bc60d9
Merge branch 'bug_styler_hidden_cols_no_sparse' into styler_to_string
attack68 Sep 8, 2021
9121aa3
no space for hidden cols
attack68 Sep 8, 2021
563754c
max_colwidth and align options
attack68 Sep 8, 2021
e78feeb
Merge remote-tracking branch 'upstream/master' into styler_to_string
attack68 Sep 8, 2021
34b8625
Merge remote-tracking branch 'upstream/master' into styler_to_string
attack68 Sep 9, 2021
15058bc
Merge remote-tracking branch 'upstream/master' into styler_to_string
attack68 Sep 12, 2021
718a15d
add docs
attack68 Sep 12, 2021
7f6aa70
add line_width and other args
attack68 Sep 15, 2021
9f2f9bf
Merge remote-tracking branch 'upstream/master' into styler_to_string
attack68 Sep 15, 2021
48a15c9
line max arg
attack68 Sep 16, 2021
7db906a
fix bug
attack68 Sep 18, 2021
ed05a90
fix bug
attack68 Sep 18, 2021
8e17483
fix bug
attack68 Sep 18, 2021
22899e4
whats new
attack68 Sep 18, 2021
036e1dc
Merge remote-tracking branch 'upstream/master' into styler_to_string
attack68 Sep 18, 2021
271bbc1
doc args
attack68 Sep 18, 2021
ff3dc53
Merge branch 'bug_styler_hide_index_latex' into styler_to_string
attack68 Sep 18, 2021
e2cd5ae
doc args
attack68 Sep 18, 2021
12b1144
Merge remote-tracking branch 'upstream/master' into styler_to_string
attack68 Nov 16, 2021
f6b98bf
simplify to_string
attack68 Nov 17, 2021
6d93a1a
simplify method
attack68 Nov 17, 2021
8e236a0
basic tests
attack68 Nov 17, 2021
c318973
whatsnew
attack68 Nov 17, 2021
5f7f940
Merge remote-tracking branch 'upstream/master' into styler_simple_to_…
attack68 Nov 30, 2021
3580f04
add to doc toc
attack68 Nov 30, 2021
db01817
fix validation
attack68 Dec 1, 2021
9145afc
fix doc build
attack68 Dec 1, 2021
4d0bbbc
Merge remote-tracking branch 'upstream/master' into styler_simple_to_…
attack68 Jan 4, 2022
3752fd4
Merge remote-tracking branch 'upstream/master' into styler_simple_to_…
attack68 Jan 7, 2022
c37fb18
push to 1.5.0
attack68 Jan 7, 2022
1672c7b
fix doc string
attack68 Jan 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/source/reference/style.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Styler properties
Styler.template_html_style
Styler.template_html_table
Styler.template_latex
Styler.template_string
Styler.loader

Style application
Expand Down Expand Up @@ -74,5 +75,6 @@ Style export and import
Styler.to_html
Styler.to_latex
Styler.to_excel
Styler.to_string
Styler.export
Styler.use
8 changes: 5 additions & 3 deletions doc/source/whatsnew/v1.5.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ including other versions of pandas.
Enhancements
~~~~~~~~~~~~

.. _whatsnew_150.enhancements.enhancement1:
.. _whatsnew_150.enhancements.styler:

enhancement1
^^^^^^^^^^^^
Styler
^^^^^^

- New method :meth:`.Styler.to_string` for alternative customisable output methods (:issue:`44502`)

.. _whatsnew_150.enhancements.enhancement2:

Expand Down
67 changes: 67 additions & 0 deletions pandas/io/formats/style.py
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,73 @@ def to_html(
html, buf=buf, encoding=(encoding if buf is not None else None)
)

def to_string(
self,
buf=None,
*,
encoding=None,
sparse_index: bool | None = None,
sparse_columns: bool | None = None,
max_rows: int | None = None,
max_columns: int | None = None,
delimiter: str = " ",
):
"""
Write Styler to a file, buffer or string in text format.

.. versionadded:: 1.5.0

Parameters
----------
buf : str, Path, or StringIO-like, optional, default None
Buffer to write to. If ``None``, the output is returned as a string.
encoding : str, optional
Character encoding setting for file output.
Defaults to ``pandas.options.styler.render.encoding`` value of "utf-8".
sparse_index : bool, optional
Whether to sparsify the display of a hierarchical index. Setting to False
will display each explicit level element in a hierarchical key for each row.
Defaults to ``pandas.options.styler.sparse.index`` value.
sparse_columns : bool, optional
Whether to sparsify the display of a hierarchical index. Setting to False
will display each explicit level element in a hierarchical key for each
column. Defaults to ``pandas.options.styler.sparse.columns`` value.
max_rows : int, optional
The maximum number of rows that will be rendered. Defaults to
``pandas.options.styler.render.max_rows``, which is None.
max_columns : int, optional
The maximum number of columns that will be rendered. Defaults to
``pandas.options.styler.render.max_columns``, which is None.

Rows and columns may be reduced if the number of total elements is
large. This value is set to ``pandas.options.styler.render.max_elements``,
which is 262144 (18 bit browser rendering).
delimiter : str, default single space
The separator between data elements.

Returns
-------
str or None
If `buf` is None, returns the result as a string. Otherwise returns `None`.
"""
obj = self._copy(deepcopy=True)

if sparse_index is None:
sparse_index = get_option("styler.sparse.index")
if sparse_columns is None:
sparse_columns = get_option("styler.sparse.columns")

text = obj._render_string(
sparse_columns=sparse_columns,
sparse_index=sparse_index,
max_rows=max_rows,
max_cols=max_columns,
delimiter=delimiter,
)
return save_to_buffer(
text, buf=buf, encoding=(encoding if buf is not None else None)
)

def set_td_classes(self, classes: DataFrame) -> Styler:
"""
Set the DataFrame of strings added to the ``class`` attribute of ``<td>``
Expand Down
19 changes: 19 additions & 0 deletions pandas/io/formats/style_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class StylerRenderer:
template_html_table = _gl01_adjust(env.get_template("html_table.tpl"))
template_html_style = _gl01_adjust(env.get_template("html_style.tpl"))
template_latex = _gl01_adjust(env.get_template("latex.tpl"))
template_string = _gl01_adjust(env.get_template("string.tpl"))

def __init__(
self,
Expand Down Expand Up @@ -183,6 +184,24 @@ def _render_latex(
d.update(kwargs)
return self.template_latex.render(**d)

def _render_string(
self,
sparse_index: bool,
sparse_columns: bool,
max_rows: int | None = None,
max_cols: int | None = None,
**kwargs,
) -> str:
"""
Render a Styler in string format
"""
self._compute()

d = self._translate(sparse_index, sparse_columns, max_rows, max_cols, blank="")

d.update(kwargs)
return self.template_string.render(**d)

def _compute(self):
"""
Execute the style functions built up in `self._todo`.
Expand Down
12 changes: 12 additions & 0 deletions pandas/io/formats/templates/string.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{% for r in head %}
{% for c in r %}{% if c["is_visible"] %}
{{ c["display_value"] }}{% if not loop.last %}{{ delimiter }}{% endif %}
{% endif %}{% endfor %}

{% endfor %}
{% for r in body %}
{% for c in r %}{% if c["is_visible"] %}
{{ c["display_value"] }}{% if not loop.last %}{{ delimiter }}{% endif %}
{% endif %}{% endfor %}

{% endfor %}
42 changes: 42 additions & 0 deletions pandas/tests/io/formats/style/test_to_string.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from textwrap import dedent

import pytest

from pandas import DataFrame

pytest.importorskip("jinja2")
from pandas.io.formats.style import Styler


@pytest.fixture
def df():
return DataFrame({"A": [0, 1], "B": [-0.61, -1.22], "C": ["ab", "cd"]})


@pytest.fixture
def styler(df):
return Styler(df, uuid_len=0, precision=2)


def test_basic_string(styler):
result = styler.to_string()
expected = dedent(
"""\
A B C
0 0 -0.61 ab
1 1 -1.22 cd
"""
)
assert result == expected


def test_string_delimiter(styler):
result = styler.to_string(delimiter=";")
expected = dedent(
"""\
;A;B;C
0;0;-0.61;ab
1;1;-1.22;cd
"""
)
assert result == expected