Python Pandas: Style column header - python

I am using pandas styler to give some columns a background color, based on the name of the column header.
While this works as intended, the background color of the column header doesn't change.
Here is the part in my script where thy style is applied:
def highlight_col(x):
if x.name in added_columns:
return ['background-color: #67c5a4']*x.shape[0]
elif x.name in dropped_columns:
return ['background-color: #ff9090']*x.shape[0]
else:
return ['background-color: None']*x.shape[0]
old = old.style.apply(highlight_col, axis=0)
Is there a way to apply the style.apply()-function not only to the cells below the column header, but the complete column including the column header?
Edit:
For clarification here is a screenshot of the excel output:
screenshot of excel output
"Header 2" should have the same background color as the cells below it.

Okay, I think I figured out a way to handle formatting a column header using html 'selectors':
Using much of your code as setup:
df = pd.DataFrame('some value', columns=['Header1','Header2','Header3'], index=np.arange(12))
added_columns = 'Header2'
dropped_columns = 'Header1'
def highlight_col(x):
if x.name in added_columns:
return ['background-color: #67c5a4']*x.shape[0]
elif x.name in dropped_columns:
return ['background-color: #ff9090']*x.shape[0]
else:
return ['background-color: None']*x.shape[0]
col_loc_add = df.columns.get_loc(added_columns) + 2
col_loc_drop = df.columns.get_loc(dropped_columns) + 2
df.style.apply(highlight_col, axis=0)\
.set_table_styles(
[{'selector': f'th:nth-child({col_loc_add})',
'props': [('background-color', '#67c5a4')]},
{'selector': f'th:nth-child({col_loc_drop})',
'props': [('background-color', '#ff9090')]}])
Output:
Note: I am using f-string which is a Python 3.6+ feature.

You can use np.vstack() to stack the column names like below and create a fresh dataframe to apply the function, then export to excel with header=False:
Using #Scott's data and piR's function,
Setup:
df = pd.DataFrame('some value', columns=['Header1','Header2','Header3'], index=np.arange(12))
def f(dat, c='red'):
return [f'background-color: {c}' for i in dat]
You can do:
pd.DataFrame(np.vstack((df.columns,df.to_numpy())),columns=df.columns).style.apply(
f,subset=['Header2']).to_excel('file.xlsx',header=False,index=False)
Output of excel file:

Related

using applymap method to color cells based on condition

I would like to color some cells (in a data frame) based on their content using pandas, I did some tries but with no required results
this is my last failed try :
import pandas as pd
import dataframe_image as dfi
df = pd.read_excel('splice traitment.xlsx', sheet_name='Sheet4', usecols="B,C,D,E,F,G,H,I,J,K")
def color_cells(val):
color = 'red' if val == 7 else ''
return 'background-color: {}'.format(color)
df.style.applymap(color_cells)
dfi.export(df,"table.png")
Thank you very much
You can pass styled DataFrame to export method:
dfi.export(df.style.applymap(color_cells),"table.png")
Or asign to variable styled:
styled = df.style.applymap(color_cells)
dfi.export(styled,"table.png")

comparing two columns and highlighting differences in dataframe

What would be the best way to compare two columns and highlight if there is a difference between two columns in dataframe?
df = pd.DataFrame({'ID':['one2', 'one3', 'one3', 'one4' ],
'Volume':[5.0, 6.0, 7.0, 2.2],
'BOX':['one','two','three','four'],
'BOX2':['one','two','five','one hundred']})
I am trying to compare the BOX column and BOX2 column and I'd like to highlight the differences between them.
Maybe you can do something like this:
df.style.apply(lambda x: (x != df['BOX']).map({True: 'background-color: red; color: white', False: ''}), subset=['BOX2'])
Output (in Jupyter):
You might try something like:
def hl(d):
df = pd.DataFrame(columns=d.columns, index=d.index)
df.loc[d['BOX'].ne(d['BOX2']), ['BOX', 'BOX2']] = 'background: yellow'
return df
df.style.apply(hl, axis=None)
output:
for the whole row:
def hl(d):
df = pd.DataFrame(columns=d.columns, index=d.index)
df.loc[d['BOX'].ne(d['BOX2'])] = 'background: yellow'
return df
df.style.apply(hl, axis=None)
output:

Highlight a column incl. header with style in Pivottable [duplicate]

I am using pandas styler to give some columns a background color, based on the name of the column header.
While this works as intended, the background color of the column header doesn't change.
Here is the part in my script where thy style is applied:
def highlight_col(x):
if x.name in added_columns:
return ['background-color: #67c5a4']*x.shape[0]
elif x.name in dropped_columns:
return ['background-color: #ff9090']*x.shape[0]
else:
return ['background-color: None']*x.shape[0]
old = old.style.apply(highlight_col, axis=0)
Is there a way to apply the style.apply()-function not only to the cells below the column header, but the complete column including the column header?
Edit:
For clarification here is a screenshot of the excel output:
screenshot of excel output
"Header 2" should have the same background color as the cells below it.
Okay, I think I figured out a way to handle formatting a column header using html 'selectors':
Using much of your code as setup:
df = pd.DataFrame('some value', columns=['Header1','Header2','Header3'], index=np.arange(12))
added_columns = 'Header2'
dropped_columns = 'Header1'
def highlight_col(x):
if x.name in added_columns:
return ['background-color: #67c5a4']*x.shape[0]
elif x.name in dropped_columns:
return ['background-color: #ff9090']*x.shape[0]
else:
return ['background-color: None']*x.shape[0]
col_loc_add = df.columns.get_loc(added_columns) + 2
col_loc_drop = df.columns.get_loc(dropped_columns) + 2
df.style.apply(highlight_col, axis=0)\
.set_table_styles(
[{'selector': f'th:nth-child({col_loc_add})',
'props': [('background-color', '#67c5a4')]},
{'selector': f'th:nth-child({col_loc_drop})',
'props': [('background-color', '#ff9090')]}])
Output:
Note: I am using f-string which is a Python 3.6+ feature.
You can use np.vstack() to stack the column names like below and create a fresh dataframe to apply the function, then export to excel with header=False:
Using #Scott's data and piR's function,
Setup:
df = pd.DataFrame('some value', columns=['Header1','Header2','Header3'], index=np.arange(12))
def f(dat, c='red'):
return [f'background-color: {c}' for i in dat]
You can do:
pd.DataFrame(np.vstack((df.columns,df.to_numpy())),columns=df.columns).style.apply(
f,subset=['Header2']).to_excel('file.xlsx',header=False,index=False)
Output of excel file:

Pandas to_mardown() highlight row

Is it possible to change the text color for a specific row when using df.to_markdown()?
I have attempted using df.style.apply([styles]).to_markdown() but does does not work since it converts the df into an styler object.
code:
print(labels_data.to_markdown(headers= df.columns, tablefmt="jira", showindex=True))
df styled code:
def row_name(x):
for i in x:
if x.name=='Control':
return ['background: yellow']
else:
return ''
labels_data = count_labels(labels).sort_values('% meets', ascending=False)
labels_data.style.apply(lambda x: ['background: lightgreen'
if (x.name == 'control')
else '' for i in x], axis=1)
My use case is printing a markdown to copy paste a table (with styles) in jira.
Thanks
Why not use html? Html is valid inline within markdown, but there isn't a standard way of marking rows within a markdown table (not that markdown is a much of standard, in practice, anyway).

Highlight rows from a DataFrame based on values in a column in Python Pandas

I have been trying to highlight some rows in a pandas dataframe based on multiple conditions.
I'm expecting that when a string in the target column match the criteria defined in the function, the entire row will be highlighted.
I tried different combinations of the .style.apply method, but it kept giving me the following error:
ValueError: style is not supported for non-unique indicies.
This is the code:
def highlight_rows(s):
if s['my_column'] == 'some_text':
return 'background-color: green'
elif s['my_column'] == 'somedifferent_text':
return 'background-color: blue'
df.style.apply(highlight_rows, axis = 0)
I'm using Python 3.6.5 and Pandas 0.22.0
Any idea on what I'm doing wrong?
Should I pass different parameters or doing a different loop?
Thank you
The apply method extracts each column or row depend on axis=0 or axis=1. Then you can add any style for each cell in rows or columns. If you want to pass your style through method, you need to assign the method expression for each element of array. Otherwise, it must be None value.
def highlight_rows(s):
con = s.copy()
con[:] = None
if (s['my_column'] == 'some_text'):
con[:] = "background-color: green"
elif (s['my_column'] == 'somedifferent_text'):
con[:] = "background-color: blue"
return con
df.style.apply(highlight_rows, axis=1)
assuming s is equal to your dataframe :
Try this:
def file():
styled = df.style.apply(highlight_rows, axis = 0)
f = open('new_file.html', 'w')
html = (styled.render())
f.write(html)
f.close()
def highlight_rows(s):
if s.my_column == 'some_text':
return ['background-color: green'] * s.size
elif s.my_column == 'somedifferent_text':
return ['background-color: blue'] * s.size

Categories