Description
Pandas Styler already contains the functionality needed for specific row
and column
styling via CSS class referencing.
Firstly it can add table_styles
within the preliminary <style>
tag, based on given selectors
.
Secondly it adds specific CSS classes to each element, be it, heading0
col1
row0
etc.
The current solution to add styling to a specific column can be done in two ways:
- Using Apply: this is kind of hinted at in the docs and how most people attack the problem initially.
df = pd.DataFrame(data=[[0,1],[1,2],[3,4]], columns=['A', 'B'])
s = df.style.set_uuid('_')
s.apply(lambda x: ['color: red' for v in x], subset=['A'])
s
The problem with this approach is that it generates a lot of HTML code, each cell needs an id, and each id is added in the
initial <style> tag as the means of identifying elements. Without manually specifying the UUID (which are typically about 45bytes long) this creates a lot of useless data transmission and slows down websites for large tables:
'<style type="text/css" >\n#T__row0_col0,#T__row1_col0,#T__row2_col0{\n color: red;\n color: red;\n color: red;\n }</style><table id="T__" ><thead> <tr> <th class="blank level0" ></th> <th class="col_heading level0 col0" >A</th> <th class="col_heading level0 col1" >B</th> </tr></thead><tbody>\n <tr>\n <th id="T__level0_row0" class="row_heading level0 row0" >0</th>\n <td id="T__row0_col0" class="data row0 col0" >0</td>\n <td id="T__row0_col1" class="data row0 col1" >1</td>\n </tr>\n <tr>\n <th id="T__level0_row1" class="row_heading level0 row1" >1</th>\n <td id="T__row1_col0" class="data row1 col0" >1</td>\n <td id="T__row1_col1" class="data row1 col1" >2</td>\n </tr>\n <tr>\n <th id="T__level0_row2" class="row_heading level0 row2" >2</th>\n <td id="T__row2_col0" class="data row2 col0" >3</td>\n <td id="T__row2_col1" class="data row2 col1" >4</td>\n </tr>\n </tbody></table>'
- Using Table Styles: since
col0
is a class identifier added to each cell relevant to column 'A' one can use table styles to apply directly:
df = pd.DataFrame(data=[[0,1],[1,2],[3,4]], columns=['A', 'B'])
s = Styler(df, uuid='_', cell_ids=False)
s.set_table_styles([{'selector': '.col0', 'props': [('color', 'red')]}])
s
This might be preferred in some instances since it can reduce the amount of HTML, particularly when combined with cell_ids
argument. It only outputs the class type and can ignore individual ids, including their UUIDs.
'<style type="text/css" > #T__ .col0 { color: red; }</style><table id="T__" ><thead> <tr> <th class="blank level0" ></th> <th class="col_heading level0 col0" >A</th> <th class="col_heading level0 col1" >B</th> </tr></thead><tbody> <tr> <th id="T__level0_row0" class="row_heading level0 row0" >0</th> <td class="data row0 col0" >0</td> <td class="data row0 col1" >1</td> </tr> <tr> <th id="T__level0_row1" class="row_heading level0 row1" >1</th> <td class="data row1 col0" >1</td> <td class="data row1 col1" >2</td> </tr> <tr> <th id="T__level0_row2" class="row_heading level0 row2" >2</th> <td class="data row2 col0" >3</td> <td class="data row2 col1" >4</td> </tr> </tbody></table>'
Therefore the only missing code is to put this together in a function which automatically maps the column name to the added CSS class and appends it to the existing table styles.
API breaking implications
This only provides new functionality and will not impact previous versions.