Change color of cell in pandas frame if cell contains a dedicated string

Dear Friends,

I have here a challenge, hoping you guys could support me. Suppose you have the following frame

import pandas as pd
import numpy as np
import streamlit as st
from st_aggrid import AgGrid
testFrame=pd.DataFrame({"col1":["Albert","Mike","John","Laura"],"col2":["New York - Violation of Rule", "London", "Berlin - Violation of Rule", "Sao Paolo"]})
grid_return=AgGrid(testFrame, editable=True)
General=grid_return["data"]

What I would like to achieve is that if a column contains the string “Violation of Rule” the cell color backround color should be white and the text color in red, something like this

Capture

I’d like to achieve this, since I have a large frame and having a color-coding approach will help my colleagues to find the important cells faster

Any support would be more than appreciated

Hi @Isaak_Saba,

Thanks for posting!

You should be able to do this with the Pandas .apply() function. This resource has some great examples.

Caroline :balloon:

Hi Caroline,

thans a lot for your support. I try to implement it via

def color_violation(val):
     color="red" if "- Violation of Rule" in str(val) else ""
     return 'color: %s' % color
General.style.applymap(color_violation)

Also if I re-write it as

General=General.style.applymap(color_violation)

I do not see the desired outcome
But if I use the command

st.write(General)

I get the outcome, however it takes really much time and I cannot change the dataframe.

Any idea how to change the code?

Hi @Isaak_Saba,

Can you clarify why you don’t want to change the dataframe? I might have misunderstood the original question

Thanks!

Caroline

Hi Caroline,
please apologies if I did not explain it well. Let me give you a short explanation in bullet points

  • I read an excel file via file_uploader
  • I I check some columns for some rules, and if rules are violated I add " - Violation of Rule in the same cell
  • I change the static frame to a dynamic one via AgGrid
  • The user can now see the dynamic frame and change data

The issue is that the frame is quite big and I would like to support the user by color coding only the cells which contain the string “- Violation of Rule” and that the frame remains dynamic

Hi @Isaak_Saba,

Thanks for clarifying! In that case, it sounds like you want AgGrid to update the formatting rather than changing the formatting of the dataframe. I’ll move this question to the AgGrid section of the forum so that the AgGrid experts can chime in :slightly_smiling_face:

Caroline

Thanks a lot. Keeping fingers crossed. Of course I am sitting now and try to find a solution :slight_smile:

I found the solution :slight_smile:
For anyone who might be interested, please find below my approach

import pandas as pd
import numpy as np
import streamlit as st
from st_aggrid import AgGrid
testFrame=pd.DataFrame({"col1":["Albert","Mike","John","Laura"],"col2":["New York - Violation of Rule", "London", "Berlin - Violation of Rule", "Sao Paolo"]})

gb = GridOptionsBuilder.from_dataframe(testFrame)
        
        cellsytle_jscode = JsCode("""
function(params){
    if (params.value.includes('Violation of Rule')) {
        return {
            'color': 'red', 
            'backgroundColor': 'white',
        }
    }
}
""")
                                            
gb.configure_columns(testFrame, cellStyle=cellsytle_jscode,editable=True)
grid_options = gb.build()
grid_return=AgGrid(testFrame, gridOptions=grid_options,allow_unsafe_jscode=True)