I have a pandas.DataFrame
with values in it, say:
df = pd.DataFrame(np.random.randn(5, 3), columns=['a', 'b', 'c'])
In [160]: df
Out[160]:
a b c
0 -0.316527 -0.721590 1.812285
1 -1.704653 -0.415888 -0.294740
2 -1.126637 0.032084 -1.344484
3 0.081789 -1.311954 1.941496
4 0.617405 0.114212 -0.763610
Now I've written my own color gradient functions so that I get a pd.DataFrame
of the same size and shape, but with color hex codes for each cell, say:
df_clrs = pd.DataFrame([
['#bc4700', '#dea380', '#bc4700'],
['#384f69', '#dea380', '#bc4700'],
['#dea380', '#bc4700', '#384f69'],
['#384f69', '#384f69', '#dea380'],
['#dea380', '#bc4700', '#384f69']],
columns=['a', 'b', 'c']
)
In [164]: df_clrs
Out[164]:
a b c
0 #bc4700 #dea380 #bc4700
1 #384f69 #dea380 #bc4700
2 #dea380 #bc4700 #384f69
3 #384f69 #384f69 #dea380
4 #dea380 #bc4700 #384f69
I let's say I've done this as well with text colors, so:
df_fnts = pd.DataFrame([
['#f1f1f1','#f1f1f1','#000000'],
['#000000','#f1f1f1','#f1f1f1'],
['#000000','#f1f1f1','#000000'],
['#f1f1f1','#000000','#f1f1f1'],
['#000000','#000000','#f1f1f1']],
columns=['a', 'b' ,'c']
)
In [167]: df_fnts
Out[167]:
a b c
0 #f1f1f1 #f1f1f1 #000000
1 #000000 #f1f1f1 #f1f1f1
2 #000000 #f1f1f1 #000000
3 #f1f1f1 #000000 #f1f1f1
4 #000000 #000000 #f1f1f1
My goal is to now expose the DatFrame.style
functionality, as demonstrated in these tutorials.
However, all of the functions demonstrated in tutorial focus on passing a function (using the pd.DataFrame.style.applymap
), however, I have all of the properties already created.
Because in the documentation it looks like you need to append the value with the appropriate property, I've created a function like this:
def _apply_prop(df, prop):
return df.applymap(lambda x: prop + ':' + x)
# apply the color mapping
df.style.applymap(
_apply_prop(
df_clrs,
'background-color'
)
).to_excel('~/Desktop/background-colors.xlsx')
But I get a TypeError
TypeError: the first argument must be callable
df
(5x3) and df_clrs
(4x3) have different shapes. Assuming you got that corrected, try this:
def _apply_prop(_, style, prop):
return style.applymap(lambda x: prop + ':' + x)
df.style.apply(_apply_prop, axis=None, style=df_clrs, prop='background-color')
Output:
Some notes:
style.applymap
. It iterates over cells. Use apply(..., axis=...)
to iterate over column / row / table. Whatever you iterate over, return an object with the same shape.apply / applymap
. You supply the function's name along with its parametersapply / applymap
implicitly passes the data frame to the styling function. You can pass additional arguments by keywords.