Skip to content

Commit 0e34c24

Browse files
committed
ENH: restructure code for no new functions, only keyword additions
1 parent b3e68d1 commit 0e34c24

File tree

4 files changed

+76
-103
lines changed

4 files changed

+76
-103
lines changed

doc/source/user_guide/style.ipynb

+6-5
Original file line numberDiff line numberDiff line change
@@ -835,19 +835,20 @@
835835
"We hope to collect some useful ones either in pandas, or preferable in a new package that [builds on top](#Extensibility) the tools here.\n",
836836
"\n",
837837
"`table_styles` can be used to add column and row based class descriptors. For large tables this can increase performance by avoiding repetitive individual css for each cell, and it can also simplify style construction in some cases.\n",
838-
"`Styler.extend_column_styles` is a specific function to set styles to individual columns.\n",
838+
"If `table_styles` is given as a dictionary each key should be a specified column or index value and this will map to specific class CSS selectors of the given column or row.\n",
839839
"\n",
840-
"Note that `Styler.set_table_styles` will overwrite existing styles (including those column based) whilst the preferred `Styler.extend_table_styles` will add to the current items."
840+
"Note that `Styler.set_table_styles` will overwrite existing styles but can be chained by setting the `overwrite` argument to `False`."
841841
]
842842
},
843843
{
844844
"cell_type": "code",
845845
"execution_count": null,
846846
"outputs": [],
847847
"source": [
848-
"html = html.extend_column_styles({\n",
849-
" 'B': [dict(selector='', props=[('color', 'blue')])]\n",
850-
"})\n",
848+
"html = html.set_table_styles({\n",
849+
" 'B': [dict(selector='', props=[('color', 'green')])],\n",
850+
" 'C': [dict(selector='td', props=[('color', 'red')])], \n",
851+
" }, overwrite=False)\n",
851852
"html"
852853
],
853854
"metadata": {

doc/source/whatsnew/v1.1.1.rst

+1-2
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ Categorical
5454
Other enhancements
5555
~~~~~~~~~~~~~~~~~~
5656

57-
- :meth:`Styler.extend_table_styles` added the supplement `Styler.set_table_styles` (:issue:`35607`)
58-
- :meth:`Styler.extend_column_styles` to directly add class based CSS to specified DataFrame columns (:issue:`35607`)
57+
- :meth:`Styler.set_table_styles` now allows the direct styling of rows and columns and can be chained (:issue:`35607`)
5958

6059
.. ---------------------------------------------------------------------------
6160

pandas/io/formats/style.py

+58-91
Original file line numberDiff line numberDiff line change
@@ -909,117 +909,84 @@ def set_caption(self, caption: str) -> "Styler":
909909
self.caption = caption
910910
return self
911911

912-
def set_table_styles(self, table_styles) -> "Styler":
912+
def set_table_styles(self, table_styles, axis=0, overwrite=True) -> "Styler":
913913
"""
914914
Set the table styles on a Styler.
915915
916916
These are placed in a ``<style>`` tag before the generated HTML table.
917917
918-
Parameters
919-
----------
920-
table_styles : list
921-
Each individual table_style should be a dictionary with
922-
``selector`` and ``props`` keys. ``selector`` should be a CSS
923-
selector that the style will be applied to (automatically
924-
prefixed by the table's UUID) and ``props`` should be a list of
925-
tuples with ``(attribute, value)``.
926-
927-
Returns
928-
-------
929-
self : Styler
930-
931-
Examples
932-
--------
933-
>>> df = pd.DataFrame(np.random.randn(10, 4))
934-
>>> df.style.set_table_styles(
935-
... [{'selector': 'tr:hover',
936-
... 'props': [('background-color', 'yellow')]}]
937-
... )
938-
"""
939-
self.table_styles = table_styles
940-
return self
941-
942-
def extend_table_styles(self, table_styles) -> "Styler":
943-
"""
944-
Extend the existing table styles on a Styler.
945-
946-
These are placed in a ``<style>`` tag before the generated HTML table.
918+
This function can be used to style the entire table, columns, rows or
919+
specific HTML selectors.
947920
948921
Parameters
949922
----------
950-
table_styles : list
951-
Each individual table_style should be a dictionary with
952-
``selector`` and ``props`` keys. ``selector`` should be a CSS
953-
selector that the style will be applied to (automatically
954-
prefixed by the table's UUID) and ``props`` should be a list of
955-
tuples with ``(attribute, value)``.
923+
table_styles : list or dict
924+
If supplying a list, each individual table_style should be a
925+
dictionary with ``selector`` and ``props`` keys. ``selector``
926+
should be a CSS selector that the style will be applied to
927+
(automatically prefixed by the table's UUID) and ``props``
928+
should be a list of tuples with ``(attribute, value)``.
929+
If supplying a dict, the dict keys should correspond to
930+
column names or index values, depending upon the specified
931+
`axis` argument. These will be mapped to row or col CSS
932+
selectors. MultiIndex values as dict keys should be
933+
in their respective tuple form. The dict values should be
934+
a list as specified in the form with CSS selectors and
935+
props that will be applied to the specified row or column.
936+
axis : {0 or 'index', 1 or 'columns', None}, default 0
937+
Apply to each column (``axis=0`` or ``'index'``), to each row
938+
(``axis=1`` or ``'columns'``). Only used if `table_styles` is
939+
dict.
940+
overwrite : boolean, default True
941+
Styles are replaced if `True`, or extended if `False`. CSS
942+
rules are preserved so most recent styles set will dominate
943+
if selectors intersect.
956944
957945
Returns
958946
-------
959947
self : Styler
960948
961949
Examples
962950
--------
963-
>>> df = pd.DataFrame(np.random.randn(10, 4))
951+
>>> df = pd.DataFrame(np.random.randn(10, 4),
952+
... columns=['A', 'B', 'C', 'D'])
964953
>>> df.style.set_table_styles(
965954
... [{'selector': 'tr:hover',
966955
... 'props': [('background-color', 'yellow')]}]
967-
... ).extend_table_styles(
968-
... [{'selector': '.col2',
969-
... 'props': [('background-color', 'blue')]}]
970-
...)
971-
"""
972-
if self.table_styles is None:
973-
return self.set_table_styles(table_styles)
974-
self.table_styles.extend(table_styles)
956+
... )
957+
>>> df.style.set_table_styles({
958+
... 'A': [{'selector': '',
959+
... 'props': [('color', 'red')]}],
960+
... 'B': [{'selector': 'td',
961+
... 'props': [('color', 'blue')]}]
962+
... }, overwrite=False)
963+
>>> df.style.set_table_styles({
964+
... 0: [{'selector': 'td:hover',
965+
... 'props': [('font-size', '25px')]}]
966+
... }, axis=1, overwrite=False)
967+
"""
968+
if isinstance(table_styles, dict):
969+
if axis == 0 or axis == 'index':
970+
obj = self.data.columns
971+
idf = '.col'
972+
else:
973+
obj = self.data.index
974+
idf = '.row'
975+
976+
_styles = []
977+
for key, styles in table_styles.items():
978+
for s in styles:
979+
c = str(obj.get_loc(key))
980+
_styles.append(
981+
{"selector": s["selector"] + idf + c, "props": s["props"]}
982+
)
983+
table_styles = _styles
984+
if not overwrite and self.table_styles is not None:
985+
self.table_styles.extend(table_styles)
986+
else:
987+
self.table_styles = table_styles
975988
return self
976989

977-
def extend_column_styles(self, column_styles) -> "Styler":
978-
"""
979-
Sets class styles for each column on a Styler.
980-
981-
These are placed in a ``<style>`` tag before the generated HTML table.
982-
983-
Parameters
984-
----------
985-
column_styles : dict
986-
Each key of the dict should be a column header with the value
987-
being a list of individual styles. Each style is a dictionary with
988-
``selector`` and ``props`` keys. ``selector`` should be a CSS
989-
selector that the style will be applied to (automatically
990-
prefixed by the table's UUID) and ``props`` should be a list of
991-
tuples with ``(attribute, value)``.
992-
993-
Returns
994-
-------
995-
self : Styler
996-
997-
Notes
998-
-----
999-
Where the ``selector`` is an empty string or `None` the ``props`` will
1000-
be applied to the column class generically.
1001-
1002-
Examples
1003-
--------
1004-
>>> df = pd.DataFrame(np.random.randn(3, 2), columns=['a', 'b'])
1005-
>>> df.style.extend_column_styles({
1006-
... 'a': [{'selector': '',
1007-
... 'props': [('font-size', '20px')]},
1008-
... {'selector': 'td:hover',
1009-
... 'props': [('color', 'pink')]}],
1010-
... 'b': [{'selector': '',
1011-
... 'props': [('font-size', '10px')]}]
1012-
... })
1013-
"""
1014-
_styles = []
1015-
for col, styles in column_styles.items():
1016-
for s in styles:
1017-
c = str(self.data.columns.get_loc(col))
1018-
_styles.append(
1019-
{"selector": s["selector"] + ".col" + c, "props": s["props"]}
1020-
)
1021-
return self.extend_table_styles(_styles)
1022-
1023990
def set_na_rep(self, na_rep: str) -> "Styler":
1024991
"""
1025992
Set the missing data representation on a Styler.

pandas/tests/io/formats/test_style.py

+11-5
Original file line numberDiff line numberDiff line change
@@ -1682,22 +1682,28 @@ def f(a, b, styler):
16821682
result = styler.pipe((f, "styler"), a=1, b=2)
16831683
assert result == (1, 2, styler)
16841684

1685-
def test_extending_table_styles(self):
1685+
def test_chaining_table_styles(self):
16861686
df = pd.DataFrame(data=[[0, 1], [1, 2]], columns=["A", "B"])
16871687
styler = df.style.set_table_styles(
16881688
[{"selector": "", "props": [("background-color", "yellow")]}]
1689-
).extend_table_styles(
1690-
[{"selector": ".col0", "props": [("background-color", "blue")]}]
1689+
).set_table_styles(
1690+
[{"selector": ".col0", "props": [("background-color", "blue")]}],
1691+
overwrite=False
16911692
)
16921693
assert len(styler.table_styles) == 2
16931694

1694-
def test_column_styling(self):
1695+
def test_column_and_row_styling(self):
16951696
df = pd.DataFrame(data=[[0, 1], [1, 2]], columns=["A", "B"])
16961697
s = Styler(df, uuid="_")
1697-
s = s.extend_column_styles(
1698+
s = s.set_table_styles(
16981699
{"A": [{"selector": "", "props": [("color", "blue")]}]}
16991700
)
17001701
assert "#T__ .col0 {\n color: blue;\n }" in s.render()
1702+
s = s.set_table_styles(
1703+
{0: [{"selector": "", "props": [("color", "blue")]}]},
1704+
axis=1
1705+
)
1706+
assert "#T__ .row0 {\n color: blue;\n }" in s.render()
17011707

17021708

17031709
@td.skip_if_no_mpl

0 commit comments

Comments
 (0)