2

I want to change the background styling color of the pandas table.

Example:

df = pd.DataFrame({
'group': ['A','B','C','D'],
'var1': [38, 1.5, 30, 4],
'var2': [29, 10, 9, 34],
'var3': [8, 39, 23, 24],
'var4': [7, 31, 33, 14],
'var5': [28, 15, 32, 14]
})

df.set_index('group', inplace=True)

I want the background color of the index cell (and just the index cell) A,C in blue and B,D in red.

I looked at the styling documentation but I could not find an example that matches this case.

2
  • 1
    It is not implemented AFAIK: pandas.pydata.org/pandas-docs/stable/user_guide/… You can only style the values, not the index or columns Commented Jun 26, 2021 at 8:41
  • 1
    @anky ok... (i was expecting that answer) Do you know how to color the whole row according to that index? Commented Jun 26, 2021 at 8:55

3 Answers 3

4

Based on the limitations of df.style, coloring index and columns is not implemented.

If you are okay to color the values based on the index, you can do something like this. Create a dictionary and apply the color based on the index using index.map

c1 = 'background-color: blue'
c2 = 'background-color: red'
d = {"A":c1,"B":c2,"C":c1,"D":c2}

df.style.apply(lambda x: x.index.map(d))

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

Yep, great choice! Do you know why if I use 'C0' instead of 'red' the code do nothing?
3

This feature is not currently available and the next release for this might be December 2021 (https://github.com/pandas-dev/pandas/pull/41893). However, you can easily work around this by using table styles. See my answer below:

df = pd.DataFrame([[1,2],[3,4],[5,6],[7,8]], index=["A", "B", "C", "D"])
green = [{'selector': 'th', 'props': 'background-color: green'}]
red = [{'selector': 'th', 'props': 'background-color: red'}]
df.style.set_table_styles({"A": green, "B": red, "C": green, "D": red}, axis=1)

enter image description here

1 Comment

You can also now use pandas map_index and apply_index functions
2

We can manipulate the underlying HTML via looking at <th> tags. One convenient way is with the BeautifulSoup library:

from bs4 import BeautifulSoup

# get the HTML representation
html = df.to_html()

# form the soup
soup = BeautifulSoup(html)

# the color categories
blues = {"A", "C"}
reds = {"B", "D"}

# for each possible "table header" tag...
for tag in soup.find_all("th"):
    # if tag's content is in `blues`...
    if tag.text in blues:
        # change the HTML style attribute accordingly
        tag["style"] = "background-color: blue;"
    # similar here..
    elif tag.text in reds:
        tag["style"] = "background-color: red;"

# get back the new HTML
new_html = str(soup)

Then, in an IPython notebook for example:

from IPython.display import HTML

HTML(new_html)

gives

enter image description here

2 Comments

great job! but I still have two questions. 1) Do you know why tag.text is printing some but not all the indexes? (in the true df not in this simplified example) 2) Why if instead of 'red' I put 'C0' the code do nothing?
Hi @FedericoVega, 1) if tag.text is neither in blues set nor reds set as defined above, then it won't be colored at all. So if for example there was another group named E, it won't be colored because it doesn't satisfy two ifs there. 2) C0 is not a valid HTML color I believe; can you clarify on what C0 is supposed to result in? A close value is #C00 which is hexadecimal representation of a color and please note the # in front. If I do this instead of red above as "background-color: #C00;", then I get something similar to red in color for B and D rows.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.