Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bokeh DataTable with conditionally coloured cells

I want to display a DataTable in bokeh, where the cells are either red or orange, according to the text content of the cell.

For example, if the cell contains the word "error", then the cell is displayed in red background. If the cells contains the word "warning", then it's orange.

I believe I should use [HTMLTemplateFormatter][1], but how?

How would I do that?

Thanks

like image 610
Carmellose Avatar asked Mar 11 '17 20:03

Carmellose


1 Answers

Looking through the documentation, you can use a HTMLTemplateFormatter and underscore js to format the table. See http://docs.bokeh.org/en/latest/docs/reference/models/widgets.tables.html and http://underscorejs.org/#template for more info. I attached an example to format based on integer values, although you could extend it as you want.

Note: this essentially imbeds a div within each table cell, so there is still a small white border around each. If possible you could resize the inner divs, or style the parent elements.

Update: depending on the bokeh version you are using you may need to include lodash or underscore js in your html document i.e. : <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/0.10.0/lodash.min.js"></script>

from bokeh.models import ColumnDataSource
from bokeh.models.widgets import DataTable, TableColumn, HTMLTemplateFormatter
from bokeh.io import show

dict1 = {'x':[0]*6,'y':[0,1,0,1,0,1]}
source = ColumnDataSource(data=dict1)

template="""
<div style="background:<%= 
    (function colorfromint(){
        if(value == 1){
            return("blue")}
        else{return("red")}
        }()) %>; 
    color: white"> 
<%= value %></div>
"""

formater =  HTMLTemplateFormatter(template=template)
columns = [
    TableColumn(field="x", title="x"),
    TableColumn(field="y", title="y",formatter=formater)
]

data_table = DataTable(source=source, columns=columns, width=800)

If you are happy to define the colors within python, a simpler method is to define the colors as a field in the column data source and reference the value in the template code.

dict1 = {'x':[0]*6, 
         'y':[0, 1, 0, 1, 0, 1],
         'color':['blue', 'red', 'blue', 'red', 'blue', 'red']}
source = ColumnDataSource(data=dict1)

template="""
<div style="background:<%=color%>"; color="white";>
<%= value %></div>
"""

formater =  HTMLTemplateFormatter(template=template)

If you are relying completely on javascript (i.e. no python based callbacks), this approach wont update the fill colors if the underlying values change.

like image 86
Anthonydouc Avatar answered Sep 29 '22 13:09

Anthonydouc