Blueboots
Blueboots

Reputation: 59

How to add a border to column headers and caption to pandas dataframe using .style?

I am trying to adding borders to the column headers and also the caption to the dataframe below. I can successfully add a border to the caption, but when I attempt to add a border around the column headers I believe it overrides the caption border and format. Is there a way to add borders to both? I tried adding two .set_table_styles() statements and I also tried incorporating them into the same chunk of code, but I must be misunderstanding how to code is being interpreted when ran.

final = unique_shows_imdb_final.style.bar(subset=["Netflix IMDb Score"], color='')\
                     .bar(subset=["Hulu IMDb Score"], color='')\
                     .bar(subset=["Prime IMDb Score"], color='')\
                     .bar(subset=["Disney+ IMDb Score"],color='').background_gradient(cmap=sns.cm.rocket_r,axis=None).hide_index().format(precision=1)

final.set_properties(subset=['Rank'], **{'font-weight': 'bold'})



final.set_properties(
    **{'border': '1px black solid !important'}
).set_table_styles([{
    'selector': '',
    'props': [('border', '2px black solid !important')]}]
).set_caption("Top 20 TV Shows per Streaming Platform").set_table_styles([{
    'selector': 'caption',
    'props': [
        ('color', 'black'),
        ('font-size', '25px'),
        ('text-align','center'),
        ('border', '3px black solid !important')
    ]
}])

Successful border around caption

final = unique_shows_imdb_final.style.bar(subset=["Netflix IMDb Score"], color='')
.bar(subset=["Hulu IMDb Score"], color='')
.bar(subset=["Prime IMDb Score"], color='')
.bar(subset=["Disney+ IMDb Score"],color='').background_gradient(cmap=sns.cm.rocket_r,axis=None).hide_index().format(precision=1)

final.set_properties(subset=['Rank'], **{'font-weight': 'bold'})



final.set_properties(
    **{'border': '1px black solid !important'}
).set_table_styles([{
    'selector': '',
    'props': [('border', '2px black solid !important')]}]
).set_caption("Top 20 TV Shows per Streaming Platform").set_table_styles([{
    'selector': 'caption',
    'props': [
        ('color', 'black'),
        ('font-size', '25px'),
        ('text-align','center'),
        ('border', '3px black solid !important')
    ]
}])

final.set_table_styles([{'selector': 'th', 'props': [('font-size', '10pt'),('border-style','solid'),('border-width','1px')]}])

Successful add of border around column header, lose formatting/border of caption

Upvotes: 0

Views: 7658

Answers (1)

Henry Ecker
Henry Ecker

Reputation: 35626

set_table_styles by default has overwrite=True.

From the Docs:

overwrite bool, default True

Styles are replaced if True, or extended if False. CSS rules are preserved so most recent styles set will dominate if selectors intersect. New in version 1.2.0.

This means that (by default) each call will overwrite the previous styles, we can set overwrite=False and also add in the missing "border-color" from the table styles:

final.set_properties(
    **{'border': '1px black solid !important'}
).set_table_styles([{
    'selector': '',
    'props': [('border', '2px black solid !important')]}]
).set_caption("Top 20 TV Shows per Streaming Platform").set_table_styles([{
    'selector': 'caption',
    'props': [
        ('color', 'black'),
        ('font-size', '25px'),
        ('text-align', 'center'),
        ('border', '3px black solid !important')
    ]
}], overwrite=False)  # Don't overwrite previous styles

final.set_table_styles([{
    'selector': 'th', 'props': [
        ('font-size', '10pt'),
        ('border-style', 'solid'),
        ('border-width', '1px'),
        ('border-color', 'black') # Missing Border Color here
    ]
}], overwrite=False)  # Don't overwrite previous styles

Sample Data:

import numpy as np
import pandas as pd

np.random.seed(5)
df = pd.DataFrame(np.random.randint(1, 100, (4, 6)))
final = df.style

Sample Output:

styled table


However, generally it is better practice to style the table last and pass a single list of selector dictionaries:

final.set_properties(
    **{'border': '1px black solid !important'}
).set_caption("Top 20 TV Shows per Streaming Platform").set_table_styles([
    # Selector 1
    {'selector': '',
     'props': [('border', '2px black solid !important')]},
    # Selector 2
    {'selector': 'caption',
     'props': [
         ('color', 'black'),
         ('font-size', '25px'),
         ('text-align', 'center'),
         ('border', '3px black solid !important')]},
    # Selector 3
    {'selector': 'th', 'props': [
        ('font-size', '10pt'),
        ('border-style', 'solid'),
        ('border-width', '1px'),
        ('border-color', 'black')  # Missing Border Color here
    ]}
])

This produces the exact same styled frame as above.

Upvotes: 4

Related Questions