Open nchesk opened 2 years ago
Hey, I'm using the so-called "walrus operator" there :=
which was introduced in Python 3.8. You'd need to be running Python 3.8 or higher. I think Anaconda defaults now to 3.9. Are you still running Python 3.7?
I updated the readme and setup.py version requirement.
Thanks a lot, I figured it out!
But can i apply style row-wise? for example:
i have dataframe with columns: index, x_val, left_val, right_val and i want to color columns x_val based on conditions:
if left_val < x_val < right_val background_color = green, elif left_val0.9 < x_val < right_val1.1 background_color = yellow else background_color = red
and i want to set color only for x_val column
but how can i pass left_val and right_val in my cell_style_dict?
thank you in advance
Formatting of one cell in a row based on another column is not something currently supported. Right now the only argument to the callable in the value in the column itself. Let me think about if there's a way to add a more row-centric conditional format.
Thanks a lot, I figured it out!
But can i apply style row-wise? for example:
i have dataframe with columns: index, x_val, left_val, right_val and i want to color columns x_val based on conditions:
if left_val < x_val < right_val background_color = green, elif left_val_0.9 < x_val < right_val_1.1 background_color = yellow else background_color = red
and i want to set color only for x_val column
but how can i pass left_val and right_val in my cell_style_dict?
thank you in advance
@nchesk I have an idea but it's not backward compatible (yet). Try my new branch multi_column_conditional
.
Here the entire row is sent in as a dictionary so you can make conditionals on the entries. So in your example:
if left_val < x_val < right_val background_color = green,
elif left_val*0.9 < x_val < right_val*1.1 background_color = yellow
else background_color = red
You could do something like:
def my_color_row(row):
if row['left_val'] < row['x_val'] < row['right_val']:
return {'className': 'table-success'}
elif row['left_val'] *.9 < row['x_val'] < 1.1 * row['right_val']:
return {'className': 'table-warning'}
return {'className':'table-danger'}
{
cell_style_dict = {'x_val': my_color_row}
}
Since you're using bootstrap I went with the bootstrap table cell classes success, warning, and danger which should give you nice compatible colors with your chosen bootstrap theme, but you can replace all the return lines with whatever style code you like.
@astrowonk thank you a lot, that is awesome
can i somehow pass left and right column names as arguments? or at least pass inside my_color_row name of column?
i have a list of them
I think you can probably make a callable that takes 2 args and/or some sort of dict comprehension that generates your style_dict. But the callable has to take a dictionary representing the whole row.
If the column names are consistent you could do something like:
def my_color_row(row,col_name):
if row[f'left_{col_name}'] < row[col_name] < row[f'right_{col_name}']:
return {'className': 'table-success'}
elif row .9 * [f'left_{col_name}'] < row[col_name] < 1.1 * row[f'right_{col_name}']:
return {'className': 'table-warning'}
return {'className':'table-danger'}
Then since you need to pass in col_name for this to work, you could use partial
to create the helper functions for each column.
from functools import partial
col_list = [] #whatever your columns are
cell_style_dict = {partial(my_color_row(col_name=col) for col in col_list }
@astrowonk thank you for your help, I really appreciate it! I'm new to this, and, unfortunately, i cannot make this work May you take a look?
here's part of my code:
tables = []
col_list = ['KF', 'KU' 'DF', 'DU']
for col in col_list:
...
#here i draw graph
...
tmp = maintable.loc[userrange[0]:userrange[1], [col, col+'_avg', col+'_min', col+'_max']].copy()
cell_style_dict = {partial(my_color_row, col_name=col)}
tables.append(dbc.Table.from_enhanced_dataframe(tmp, columns=tmp.columns, cell_style_dict=cell_style_dict))
and i'm getting this error:
Traceback (most recent call last):
File "C:\Anaconda3\lib\site-packages\dash_dataframe_table\__init__.py", line 82, in enhanced_from_dataframe
markdown_columns=markdown_columns) for x in data_dict
File "C:\Anaconda3\lib\site-packages\dash_dataframe_table\__init__.py", line 82, in <listcomp>
markdown_columns=markdown_columns) for x in data_dict
File "C:\Anaconda3\lib\site-packages\dash_dataframe_table\__init__.py", line 176, in _make_row
process_table_cell(x, link_names) for x in col_names
File "C:\Anaconda3\lib\site-packages\dash_dataframe_table\__init__.py", line 177, in <listcomp>
if not str(x).endswith(link_column_suffix)
File "C:\Anaconda3\lib\site-packages\dash_dataframe_table\__init__.py", line 113, in process_table_cell
cell_style_entry = cell_style_dict.get(col_name)
AttributeError: 'set' object has no attribute 'get'
you're not quite making a dict comprehension there.
It looks like each table is only one row (col) with the boundaries? so 3 columns total? and you only want to style the one column. So i think you don't even need a dict comprehension just:
cell_style_dict = {col:partial(my_color_row, col_name=col)}
hi! thanks for this awesome project!
I have an issue when i try to import it:
File "C:\Anaconda3\lib\site-packages\dash_dataframe_table__init__.py", line 114 if cell_style_entry := cell_style_dict.get(col_name): ^ SyntaxError: invalid syntax
Can you help me out a bit?
Update:
I figured out that its due to python version.
I have another question: can i format cell based on value in different column?