Why background_gradient is not working for two different colors?

Question:

I’m trying to put background gradient in different colors for different columns. Why the last color override the one before? What to to do to keep both colors?

import pandas as pd
import numpy as np
arrays = [np.hstack([['One']*2, ['Two']*2]) , ['A', 'B', 'A', 'B']]
columns = pd.MultiIndex.from_arrays(arrays)
data =  pd.DataFrame(np.random.randn(5, 4), columns=list('ABCD'))
data.columns = columns 
import seaborn as sns
cm = sns.light_palette("green", as_cmap=True)
cc = sns.light_palette("red", as_cmap=True)
data.style.background_gradient(cmap=cm, subset=data.columns.get_loc_level('A', level=1)[0])
data.style.background_gradient(cmap=cc, subset=data.columns.get_loc_level('B', level=1)[0])
Asked By: project.py

||

Answers:

Each call to DataFrame.style produces a unique styler object. This is so the same DataFrame can be easily styled in different ways without affecting each other.

To apply compounding styles, or multiple styles in general, either store the returned styler as a variable and reuse it:

cm = sns.light_palette("green", as_cmap=True)
cc = sns.light_palette("red", as_cmap=True)
styler = data.style  # Keep Styler for reuse
styler.background_gradient(
    cmap=cm,
    subset=data.columns.get_loc_level('A', level=1)[0]
)
styler.background_gradient(
    cmap=cc,
    subset=data.columns.get_loc_level('B', level=1)[0]
)

Or chain the single styler object:

cm = sns.light_palette("green", as_cmap=True)
cc = sns.light_palette("red", as_cmap=True)
data.style.background_gradient(
    cmap=cm,
    subset=data.columns.get_loc_level('A', level=1)[0]
).background_gradient(
    cmap=cc,
    subset=data.columns.get_loc_level('B', level=1)[0]
)

Both produce styled table:

styled dataframe


Reproducible with seed 5:

import numpy as np
import pandas as pd
import seaborn as sns

np.random.seed(5)
data = pd.DataFrame(
    np.random.randn(5, 4),
    columns=pd.MultiIndex.from_product([['One', 'Two'], ['A', 'B']])
)
Answered By: Henry Ecker

I can’t apply twice the background_gradient. I try to do an html heatmap with two rules on the same df. I use a [-2;0] and [0;2] ranges (gradient red if outside the [-2,2], gradient green otherwise. But the [0;2] seems to overrides the first one.
And when I switch the rules, it does not work neither.

styler = df.style
styler6.background_gradient(
cmap='RdYlGn',
vmin=-2.0,
vmax=0.0,
subset=pd.IndexSlice[sbx[:-1], :],
axis=None,
low=1,
high=1
).background_gradient(
cmap='RdYlGn_r',
vmin=0.0,
vmax=2.0,
subset=pd.IndexSlice[sbx[:-1], :],
axis=None,
low=1,
high=1)

Does anyone have an idea why ?

Answered By: Pierer