Skip to content

Commit 445bb9f

Browse files
authored
CLN: simplify Styler._translate (#43686)
1 parent 7f2b418 commit 445bb9f

File tree

6 files changed

+222
-111
lines changed

6 files changed

+222
-111
lines changed

doc/source/user_guide/style.ipynb

+23-20
Original file line numberDiff line numberDiff line change
@@ -1047,7 +1047,7 @@
10471047
"source": [
10481048
"### 5. If every byte counts use string replacement\n",
10491049
"\n",
1050-
"You can remove unnecessary HTML, or shorten the default class names with string replace functions."
1050+
"You can remove unnecessary HTML, or shorten the default class names by replacing the default css dict. You can read a little more about CSS [below](#More-About-CSS-and-HTML)."
10511051
]
10521052
},
10531053
{
@@ -1056,21 +1056,24 @@
10561056
"metadata": {},
10571057
"outputs": [],
10581058
"source": [
1059-
"html = Styler(df4, uuid_len=0, cell_ids=False)\\\n",
1060-
" .set_table_styles([{'selector': 'td', 'props': props},\n",
1061-
" {'selector': '.col1', 'props': 'color:green;'},\n",
1062-
" {'selector': '.level0', 'props': 'color:blue;'}])\\\n",
1063-
" .to_html()\\\n",
1064-
" .replace('blank', '')\\\n",
1065-
" .replace('data', '')\\\n",
1066-
" .replace('level0', 'l0')\\\n",
1067-
" .replace('col_heading', '')\\\n",
1068-
" .replace('row_heading', '')\n",
1069-
"\n",
1070-
"import re\n",
1071-
"html = re.sub(r'col[0-9]+', lambda x: x.group().replace('col', 'c'), html)\n",
1072-
"html = re.sub(r'row[0-9]+', lambda x: x.group().replace('row', 'r'), html)\n",
1073-
"print(html)"
1059+
"my_css = {\n",
1060+
" \"row_heading\": \"\",\n",
1061+
" \"col_heading\": \"\",\n",
1062+
" \"index_name\": \"\",\n",
1063+
" \"col\": \"c\",\n",
1064+
" \"row\": \"r\",\n",
1065+
" \"col_trim\": \"\",\n",
1066+
" \"row_trim\": \"\",\n",
1067+
" \"level\": \"l\",\n",
1068+
" \"data\": \"\",\n",
1069+
" \"blank\": \"\",\n",
1070+
"}\n",
1071+
"html = Styler(df4, uuid_len=0, cell_ids=False)\n",
1072+
"html.set_table_styles([{'selector': 'td', 'props': props},\n",
1073+
" {'selector': '.c1', 'props': 'color:green;'},\n",
1074+
" {'selector': '.l0', 'props': 'color:blue;'}],\n",
1075+
" css_class_names=my_css)\n",
1076+
"print(html.to_html())"
10741077
]
10751078
},
10761079
{
@@ -1079,8 +1082,7 @@
10791082
"metadata": {},
10801083
"outputs": [],
10811084
"source": [
1082-
"from IPython.display import HTML\n",
1083-
"HTML(html)"
1085+
"html"
10841086
]
10851087
},
10861088
{
@@ -1658,6 +1660,7 @@
16581660
" + `row<m>`, where `m` is the numeric position of the cell.\n",
16591661
" + `col<n>`, where `n` is the numeric position of the cell.\n",
16601662
"- Blank cells include `blank`\n",
1663+
"- Trimmed cells include `col_trim` or `row_trim`\n",
16611664
"\n",
16621665
"The structure of the `id` is `T_uuid_level<k>_row<m>_col<n>` where `level<k>` is used only on headings, and headings will only have either `row<m>` or `col<n>` whichever is needed. By default we've also prepended each row/column identifier with a UUID unique to each DataFrame so that the style from one doesn't collide with the styling from another within the same notebook or page. You can read more about the use of UUIDs in [Optimization](#Optimization).\n",
16631666
"\n",
@@ -2020,7 +2023,7 @@
20202023
],
20212024
"metadata": {
20222025
"kernelspec": {
2023-
"display_name": "Python 3",
2026+
"display_name": "Python 3 (ipykernel)",
20242027
"language": "python",
20252028
"name": "python3"
20262029
},
@@ -2034,7 +2037,7 @@
20342037
"name": "python",
20352038
"nbconvert_exporter": "python",
20362039
"pygments_lexer": "ipython3",
2037-
"version": "3.8.6"
2040+
"version": "3.9.5"
20382041
}
20392042
},
20402043
"nbformat": 4,

doc/source/whatsnew/v1.4.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ Styler
8080
- Global options have been extended to configure default ``Styler`` properties including formatting and encoding and mathjax options and LaTeX (:issue:`41395`)
8181
- Naive sparsification is now possible for LaTeX without the multirow package (:issue:`43369`)
8282
- :meth:`Styler.to_html` omits CSSStyle rules for hidden table elements (:issue:`43619`)
83+
- Custom CSS classes can now be directly specified without string replacement (:issue:`43686`)
8384

8485
Formerly Styler relied on ``display.html.use_mathjax``, which has now been replaced by ``styler.html.mathjax``.
8586

pandas/io/formats/style.py

+41-4
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,10 @@ class Styler(StylerRenderer):
146146
Attributes
147147
----------
148148
env : Jinja2 jinja2.Environment
149-
template : Jinja2 Template
149+
template_html : Jinja2 Template
150+
template_html_table : Jinja2 Template
151+
template_html_style : Jinja2 Template
152+
template_latex : Jinja2 Template
150153
loader : Jinja2 Loader
151154
152155
See Also
@@ -182,6 +185,11 @@ class Styler(StylerRenderer):
182185
183186
* Blank cells include ``blank``
184187
* Data cells include ``data``
188+
* Trimmed cells include ``col_trim`` or ``row_trim``.
189+
190+
Any, or all, or these classes can be renamed by using the ``css_class_names``
191+
argument in ``Styler.set_table_classes``, giving a value such as
192+
*{"row": "MY_ROW_CLASS", "col_trim": "", "row_trim": ""}*.
185193
"""
186194

187195
def __init__(
@@ -1159,6 +1167,7 @@ def _copy(self, deepcopy: bool = False) -> Styler:
11591167
- caption
11601168
11611169
Non-data dependent attributes [copied and exported]:
1170+
- css
11621171
- hidden index state and hidden columns state (.hide_index_, .hide_columns_)
11631172
- table_attributes
11641173
- table_styles
@@ -1185,6 +1194,7 @@ def _copy(self, deepcopy: bool = False) -> Styler:
11851194
"template_html",
11861195
]
11871196
deep = [ # nested lists or dicts
1197+
"css",
11881198
"_display_funcs",
11891199
"_display_funcs_index",
11901200
"_display_funcs_columns",
@@ -1948,9 +1958,10 @@ def set_sticky(
19481958

19491959
def set_table_styles(
19501960
self,
1951-
table_styles: dict[Any, CSSStyles] | CSSStyles,
1961+
table_styles: dict[Any, CSSStyles] | CSSStyles | None = None,
19521962
axis: int = 0,
19531963
overwrite: bool = True,
1964+
css_class_names: dict[str, str] | None = None,
19541965
) -> Styler:
19551966
"""
19561967
Set the table styles included within the ``<style>`` HTML element.
@@ -1990,6 +2001,11 @@ def set_table_styles(
19902001
19912002
.. versionadded:: 1.2.0
19922003
2004+
css_class_names : dict, optional
2005+
A dict of strings used to replace the default CSS classes described below.
2006+
2007+
.. versionadded:: 1.4.0
2008+
19932009
Returns
19942010
-------
19952011
self : Styler
@@ -2001,6 +2017,22 @@ def set_table_styles(
20012017
Styler.set_table_attributes: Set the table attributes added to the ``<table>``
20022018
HTML element.
20032019
2020+
Notes
2021+
-----
2022+
The default CSS classes dict, whose values can be replaced is as follows:
2023+
2024+
.. code-block:: python
2025+
2026+
css_class_names = {"row_heading": "row_heading",
2027+
"col_heading": "col_heading",
2028+
"index_name": "index_name",
2029+
"col": "col",
2030+
"col_trim": "col_trim",
2031+
"row_trim": "row_trim",
2032+
"level": "level",
2033+
"data": "data",
2034+
"blank": "blank}
2035+
20042036
Examples
20052037
--------
20062038
>>> df = pd.DataFrame(np.random.randn(10, 4),
@@ -2036,10 +2068,15 @@ def set_table_styles(
20362068
See `Table Visualization <../../user_guide/style.ipynb>`_ user guide for
20372069
more details.
20382070
"""
2039-
if isinstance(table_styles, dict):
2071+
if css_class_names is not None:
2072+
self.css = {**self.css, **css_class_names}
2073+
2074+
if table_styles is None:
2075+
return self
2076+
elif isinstance(table_styles, dict):
20402077
axis = self.data._get_axis_number(axis)
20412078
obj = self.data.index if axis == 1 else self.data.columns
2042-
idf = ".row" if axis == 1 else ".col"
2079+
idf = f".{self.css['row']}" if axis == 1 else f".{self.css['col']}"
20432080

20442081
table_styles = [
20452082
{

0 commit comments

Comments
 (0)