Search code examples
javascriptpythonplotbokeh

Bokeh HoverTool custom font and newlines from Python


My tooltips on my plot are much too large and overflow the plot, as the strings they display are long. I have been browsing around the source (and a bit of the javascript), but haven't found anywhere that might let me set the font without spinning my own HTML or JavaScript (i.e. via some Python object). I've also tried naively adding <br> and \n characters into the tooltip string, but that didn't work.

How can I change my tooltip fonts (or possibly other relevant attributes) easily?

Update: I've tried setting the font small, but am still unable to get newlines in the tooltip. Here is my tooltip code:

hover.tooltips = """ y: $y <br> date: @dates <br> items: <br><font face="Arial" size="1">@items</font> """

The issue is, each item from the items source is a variable length list, and I wish to separate each entry in the list by a newline rendered in the tooltip

Example screenshot


Solution

  • After doing lots of digging around, it seemed impossible with the current version of Bokeh without doing some source editing.

    I was able to achieve the effect newlines by changing the way bokeh.js parses the strings

    in my ColumnDataSource with the keyword argument items = [['point0item0<br>', 'point0item1<br>'],['point1item1<br>', ...], ...]

    I changed the parsing of collection tooltips (doesn't work for raw string tooltips) in bokeh.js so that it would respect <br> items in the strings it renders by changing the code from

    value = Util.replace_placeholders(value, ds, i, vars);
    td.append($('<span>').html(value));
    

    to

    value = Util.replace_placeholders(value, ds, i, vars);
    value = value.replace(/,/g, "");
    value = value.replace(/&lt;/g, "<");
    value = value.replace(/&gt;/g, ">");
    td.append($('<span>').html(value));
    

    I haven't tested this beyond my example, and I hardly ever write javascript, so user beware. I also noticed that the .html(value) call changed from .text(value) between Bokeh version (0.9.2) and (0.9.3), so that any HTML code in the value string would be respected, but the <br> were already encoded (in my mind, 'broken' ;) by Util.replace_placeholders()

    In Python, the tooltip setting looks like this:

    hover.tooltips=[
            ("grade", "$y"),
            ("date", "@dates"),
            ("items", "@items"),
        ]
    

    A screenshot of hovering over the same data point now looks like this

    four strings separated by HTML newlines