I was wondering how to highlight diagonal elements of pandas dataframe using df.style
method.
I found this official link where they discuss how to highlight maximum value, but I am having difficulty creating function to highlight the diagonal elements.
Here is an example:
import numpy as np
import pandas as pd
df = pd.DataFrame({'a':[1,2,3,4],'b':[1,3,5,7],'c':[1,4,7,10],'d':[1,5,9,11]})
def highlight_max(s):
'''
highlight the maximum in a Series yellow.
'''
is_max = s == s.max()
return ['background-color: yellow' if v else '' for v in is_max]
df.style.apply(highlight_max)
This gives following output:
I am wanting a yellow highlight across the diagonal elements 1,3,7,11 only.
How to do that?
One way to conditionally format your Pandas DataFrame is to highlight cells which meet certain conditions. To do so, we can write a simple function and pass that function into the Styler object using . apply() or .
Slicing using the [] operator selects a set of rows and/or columns from a DataFrame. To slice out a set of rows, you use the following syntax: data[start:stop] . When slicing in pandas the start bound is included in the output. The stop bound is one step BEYOND the row you want to select.
Slicing a DataFrame in Pandas includes the following steps:Ensure Python is installed (or install ActivePython) Import a dataset. Create a DataFrame. Slice the DataFrame.
Let us see how to highlight specific columns of a Pandas DataFrame. We can do this using the apply () function of the Styler class. func : function should take a Series or DataFrame (depending on-axis), and return an object with the same shape. Must return a DataFrame with identical index and column labels when axis = None.
Pandas Styling API As we mentioned pandas also have a styling system that lets you customize some aspects of its the rendered dataframe, using CSS. You write a “style functions” that take scalars, DataFrame or Series, and return like-indexed DataFrames or Series with CSS "attribute: value" pairs for the values.
The Styler instance provides us with a method named bar () which lets us create a bar chart inside of the data frame. bar (subset=None,axis=0,color='#d65f5f',width=100, align='left') - This method can create bar inside of pandas data frame based on the value of that cell.
In a nutshell, Pandas does everything you need to explore your datasets in Python. If you ever try to explain data by showing your raw DataFrame to someone, you will confuse them more than providing understanding. Styling your DataFrame to make what is important stand out will help you deliver the message more clearly.
Using axis=None
we can use numpy to easily set the diagonal styles (Credit for this goes to @CJR)
import numpy as np
import pandas as pd
def highlight_diag(df):
a = np.full(df.shape, '', dtype='<U24')
np.fill_diagonal(a, 'background-color: yellow')
return pd.DataFrame(a, index=df.index, columns=df.columns)
df.style.apply(highlight_diag, axis=None)
Original, really hacky solution
a = np.full(df.shape, '', dtype='<U24')
np.fill_diagonal(a, 'background-color: yellow')
df_diag = pd.DataFrame(a,
index=df.index,
columns=df.columns)
def highlight_diag(s, df_diag):
return df_diag[s.name]
df.style.apply(highlight_diag, df_diag=df_diag)
The trick is to use the axis=None
parameter of the df.style.apply
function in order to access the entire dataset:
import numpy as np
import pandas as pd
df = pd.DataFrame({'a':[1,2,3,4],'b':[1,3,5,7],'c':[1,4,7,10],'d':[1,5,9,11]})
def highlight_diag(data, color='yellow'):
'''
highlight the diag values in a DataFrame
'''
attr = 'background-color: {}'.format(color)
# create a new dataframe of the same structure with default style value
df_style = data.replace(data, '')
# fill diagonal with highlight color
np.fill_diagonal(df_style.values, attr)
return df_style
df.style.apply(highlight_diag, axis=None)
The other answer is pretty good but I already wrote this so....
def style_diag(data):
diag_mask = pd.DataFrame("", index=data.index, columns=data.columns)
min_axis = min(diag_mask.shape)
diag_mask.iloc[range(min_axis), range(min_axis)] = 'background-color: yellow'
return diag_mask
df = pd.DataFrame({'a':[1,2,3,4],'b':[1,3,5,7],'c':[1,4,7,10],'d':[1,5,9,11]})
df.style.apply(style_diag, axis=None)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With