Reputation: 157
Try to use background color in the style not sure if this is the right way
I think I should use if elif statement but it give me errors as well. I think I have to use loc or iloc for the particular column I am interested in cause there are different columns
The main one with this code is
ValueError: Function <function flt_cat_style_function_1 at 0x7f08ea52b830> returned the wrong shape.
Result has shape: (1,)
Expected shape: (11, 1)
a=df['flt_cat']
def flt_cat_style_function_1(a):
df['flt_cat'].str.contains(r'VLIFR','background-color: #9400D3')
df['flt_cat'].str.contains(r'LIFR','background-color: #FFA500')
df['flt_cat'].str.contains(r'IFR','background-color: #FF0000')
df['flt_cat'].str.contains(r'MVFR','background-color: #FFFF00')
df['flt_cat'].str.contains(r'VFR','background-color: #00b050')
highlighted=df.style.apply(flt_cat_style_function_1,subset='flt_cat').render()
0 VLIFR
1 LIFR
2 LIFR
3 LIFR
4 IFR
5 IFR
6 MVFR
7 MVFR
8 MVFR
9 MVFR
10 VFR
Name: flt_cat, dtype: object
with open('shtml.html','w') as f:
f.write(highlighted)
Upvotes: 0
Views: 961
Reputation: 658
Your code has a couple issues:
First, the second parameter of Series.str.contains()
is case
, a boolean which decides if the contains function should match case-sensitive or not. In your code, you put your background-color strings there, which evaluate to True but don't actually do what you want. You should take a look at the function's documentation here.
Second, Series.str.contains()
returns an Index of Booleans that indicate which cells of the Series contain a string, but it doesn't modify the Series in place. So your function flt_cat_style_function_1()
actually does nothing.
Third, since the function also has no return statement, it will default to returning None
. However, df.style.apply()
expects a function that returns an array-like containing exactly 11 values (the amount of rows in df
). This is why you are seeing the ValueError.
I would suggest the following changes:
First, put your mapping of values to background-colors into a dictionary:
cell_bg_colors = {
'VLIFR': '#9400D3',
'LIFR': '#FFA500',
'IFR': '#FF0000',
'MVFR': '#FFFF00',
'VFR': '#00b050',
}
Create a function that maps one cell to it's corresponding style:
def color_background(cell):
for value, color in cell_bg_colors.items():
if value in cell:
return "background-color: {}".format(color)
return "" # default: do nothing
Then, use Styler.applymap
to apply this function to each individual cell:
highlighted = df.style.applymap(color_background, subset="flt_cat").render()
Finally, you can save highlighted
to your file.
This code is only garantueed to work correctly in Python 3.7+, as earlier versions don't guarantee dictionary order to be preserved (although Python 3.6 already keeps the order in tact). For your example, this could for example mean that the IFR color gets applied to VLIFR or LIFR cells as well in earlier Python versions.
Upvotes: 2