Below is some code which produces a styled DataFrame in Pandas. I would like to implement some additional styling to the WoW and MoM columns such that any positive integer value is colored in green, negative integer value is colored in red, and anything else is automatic.
I am referring to this documentation for examples to learn from:
https://pandas.pydata.org/docs/reference/api/pandas.io.formats.style.Styler.map.html
https://pandas.pydata.org/docs/user_guide/style.html#Acting-on-Data
I don’t understand how to implement multiple styler functions since styling applied to the DF directly (per the documentation) is removed by my subsequent code when the styler is established.
What is the correct pattern here to layer additional styling? My attempts are resulting in: 'Styler' object has no attribute 'map'
error.
Reproducible code:-
import pandas as pd
df = pd.DataFrame(index=pd.Index(['KPI ABC', 'KPI DEF', 'KPI GHI', 'KPI JKL']),
columns=pd.MultiIndex.from_product([
['North America', 'Europe', 'Asia'],
['Weekly', 'Monthly'],
['WK-01', 'WK-02', 'WK-03', 'WK-04', 'WK-05', 'WoW', 'Jan', 'Feb', 'Mar', 'MoM']]))
df.at['KPI ABC', ('North America', 'Weekly', 'WoW')] = 1.44
df.at['KPI ABC', ('Europe', 'Monthly', 'MoM')] = -0.24
df.at['KPI ABC', ('Asia', 'Monthly', 'MoM')] = 0
mapper = {('North America', 'Weekly', 'WoW'): '{0:.2f}%',
('Europe', 'Monthly', 'MoM'): '{0:.2f}%',
('Asia', 'Monthly', 'MoM'): '{0:.2f}%'}
s = df.style.format(mapper).hide([
('North America', 'Weekly', 'Jan'),
('North America', 'Weekly', 'Feb'),
('North America', 'Weekly', 'Mar'),
('North America', 'Weekly', 'MoM'),
('North America', 'Monthly', 'WK-01'),
('North America', 'Monthly', 'WK-02'),
('North America', 'Monthly', 'WK-03'),
('North America', 'Monthly', 'WK-04'),
('North America', 'Monthly', 'WK-05'),
('North America', 'Monthly', 'WoW'),
('Europe', 'Weekly', 'Jan'),
('Europe', 'Weekly', 'Feb'),
('Europe', 'Weekly', 'Mar'),
('Europe', 'Weekly', 'MoM'),
('Europe', 'Monthly', 'WK-01'),
('Europe', 'Monthly', 'WK-02'),
('Europe', 'Monthly', 'WK-03'),
('Europe', 'Monthly', 'WK-04'),
('Europe', 'Monthly', 'WK-05'),
('Europe', 'Monthly', 'WoW'),
('Asia', 'Weekly', 'Jan'),
('Asia', 'Weekly', 'Feb'),
('Asia', 'Weekly', 'Mar'),
('Asia', 'Weekly', 'MoM'),
('Asia', 'Monthly', 'WK-01'),
('Asia', 'Monthly', 'WK-02'),
('Asia', 'Monthly', 'WK-03'),
('Asia', 'Monthly', 'WK-04'),
('Asia', 'Monthly', 'WK-05'),
('Asia', 'Monthly', 'WoW')],
axis="columns")
cell_hover = {'selector': 'td:hover', 'props': [('background-color', '#ffffb3')]}
headers = {'selector': 'th:not(.index_name)', 'props': 'background-color: #000066; color: white;'}
global_left_align = {'selector': 'th', 'props': 'text-align: left'}
s = s.set_table_styles([cell_hover, headers, global_left_align])
border_styles = {
('North America', 'Weekly', 'WoW'): {'selector': 'th, td', 'props': 'border-left: 1px solid #000066; border-right: 1px solid #000066'},
('North America', 'Monthly', 'MoM'): {'selector': 'th, td', 'props': 'border-left: 1px solid #000066; border-right: 1px solid #000066'},
('Europe', 'Weekly', 'WoW'): {'selector': 'th, td', 'props': 'border-left: 1px solid #000066; border-right: 1px solid #000066'},
('Europe', 'Monthly', 'MoM'): {'selector': 'th, td', 'props': 'border-left: 1px solid #000066; border-right: 1px solid #000066'},
('Asia', 'Weekly', 'WoW'): {'selector': 'th, td', 'props': 'border-left: 1px solid #000066; border-right: 1px solid #000066'},
('Asia', 'Monthly', 'MoM'): {'selector': 'th, td', 'props': 'border-left: 1px solid #000066; border-right: 1px solid #000066'}
}
for key, value in border_styles.items():
s = s.set_table_styles({key: [value]}, overwrite=False, axis=0)
s = s.set_table_styles([{'selector': 'th.col_heading', 'props': 'text-align: center;'}], overwrite=False)
def larger_headers(val):
if val in ['North America', 'Europe', 'Asia']:
return 'font-size: 16pt'
return ''
s = s.applymap_index(larger_headers, axis='columns', level=0)
tooltips = pd.DataFrame('', index=df.index, columns=df.columns)
tooltips.at['KPI JKL', ('Europe', 'Monthly', 'Feb')] = 'Tooltip for Europe, Monthly, Feb [KPI JKL]'
tooltips.at['KPI GHI', ('Asia', 'Weekly', 'WK-04')] = 'Tooltip for Asia, Weekly, WK-04 [KPI GHI]'
s = s.set_tooltips(tooltips)
html = s.to_html()
tooltips_index = {
'KPI ABC': 'Tooltip for KPI ABC',
'KPI DEF': 'Tooltip for KPI DEF',
'KPI GHI': 'Tooltip for KPI GHI',
'KPI JKL': 'Tooltip for KPI JKL'
}
for kpi, tooltip in tooltips_index.items():
html = html.replace(f'>{kpi}<', f' title="{tooltip}">{kpi}<')
with open('styled_table_with_index_tooltips.html', 'w') as f:
f.write(html)
from IPython.core.display import display, HTML
display(HTML(html))