I have a Bokeh DataTable and would like to to compare each cell from row 1 with the cells from all other rows and highlight cells with differing values. This is what I came up with so far:
import pandas as pd
from bokeh.models import HTMLTemplateFormatter, DataTable, TableColumn
from bokeh.plotting import show, output_notebook
output_notebook()
df = pd.DataFrame({'x':[1,2,3,1], 'y':[2,2,2,3]})
def get_html_formatter(my_col, reference_vals):
template = """
<div style="background:<%=
(function colorfromint() {
if(!vals.includes(my_column)) {
console.log('Success!');
console.log(my_column);
return('red');
}
else {
console.log('Fail');
}
}()) %>;
color: black">
<%= value %>
</div>
""".replace('my_column', my_col).replace('vals', str(reference_vals))
return HTMLTemplateFormatter(template=template)
reference_values = df.iloc[0].to_list()
table = DataTable()
table.source.data = df
table.columns = [TableColumn(field=c, title=c, formatter=get_html_formatter(c, reference_values)) for c in df.columns]
show(table)
It works, but the results aren't correct because I just created a list with the values from the first row and compare every cell value against it without taking the specific columns into account.
I hope I did understand you and you want to format each column by the first value of the column.
In that case you are very close to a working solution. You only have to pass one value instead a list to the formatter, which is created by column.
import pandas as pd
from bokeh.models import HTMLTemplateFormatter, DataTable, TableColumn
from bokeh.plotting import show, output_notebook
output_notebook()
df = pd.DataFrame({'x':[1,2,3,1], 'y':[2,2,2,3]})
def get_html_formatter(my_col, reference_val):
template = """
<div style="background:<%=
(function (){return (vals != my_column ? 'red': '')}())
%>;
color: black">
<%= value %>
</div>
""".replace('my_column', my_col).replace('vals', str(reference_val))
return HTMLTemplateFormatter(template=template)
reference_values = df.iloc[0].to_list()
table = DataTable()
table.source.data = df
table.columns = [
TableColumn(field=c, title=c, formatter=get_html_formatter(c, reference_value))
for c, reference_value in zip(df.columns, reference_values) # main change here
]
show(table)
This gives the table below: