简体   繁体   中英

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 spinning my own HTML or JavaScript (ie via some Python object).旋转我自己的 HTML 或 JavaScript(即通过一些 Python 对象)的设置字体的地方。 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?

: 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

示例截图

You can use a custom tooltip , which should let you do what you need.

At the moment, you've probably got something like:

hover.tooltips = [
    ("index", "$index"),
    ("foo", "@foo"),
    ("bar", "@bar"),
]

Try:

hover.tooltips = """
    The index of my data is: $index <br>
    My foo property is bold <strong>@foo</strong>
    I could use a custom font <font face="Arial" size="3">@bar </font>
"""

You can see examples in the docs link above and in a couple of examples that are in the bokeh repo:

https://github.com/bokeh/bokeh/blob/master/examples/interactions/us_marriages_divorces/us_marriages_divorces_interactive.py#L64

https://github.com/bokeh/bokeh/blob/master/examples/glyphs/sprint.py#L90

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

由 HTML 换行符分隔的四个字符串

I know this issue is old but neither answer helped me solve the problem, which is to somehow add newlines into a single variable's rendered tooltip string.

TL;DR

Use {safe} to prevent HTML escapes and manually change the tooltip strings to add HTML <br> linebreaks.


@birdsarah's answer helped to added newlines between the tooltip strings of different variables. @eqzx's accepted answer involved editing bokeh source code, which wasn't an option for me. Neither answer enabled line breaks for data that were in lists.

Googling around, I came across this discourse thread that pointed to the {safe} modifier, which is documented but I hadn't noticed it.

You basically have to do two things:

  1. Manually add HTML linebreaks in the items column to separate each item in the list.
  2. Add the {safe} modifier to the item's tooltip so that HTML characters are not escaped.

Lets suppose your data is in a pd.DataFrame , and that the items column holds lists for each cell in the data frame.

data.items = data.items.transform(lambda x: "<br>".join(x))

...

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

This will split each item in the @items column and render them in separate lines in the tooltip string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM