Fixed HoverTool TOOLTIPS when taping an element of a Bokeh plot

本小妞迷上赌 提交于 2020-03-18 00:52:32

问题


Similar to the hovertool, I would like that when I tap on an element of the plot (in this case a circle), there is a window that pop up with information regarding the element (see picture below). And if I move the mouse after clicking on the element the window stays displaying. Is there is there a tooltip for taptool? I tried very hard to do so by using CustomJS but there is no way to display html content. Does anyone know how to proceed?

from bokeh.plotting import figure, output_file, show, ColumnDataSource

output_file("toolbar.html")

source = ColumnDataSource(data=dict(
x=[1, 2, 3, 4, 5],
y=[2, 5, 8, 2, 7],
desc=['A', 'b', 'C', 'd', 'E'],
imgs=[
    'https://docs.bokeh.org/static/snake.jpg',
    'https://docs.bokeh.org/static/snake2.png',
    'https://docs.bokeh.org/static/snake3D.png',
    'https://docs.bokeh.org/static/snake4_TheRevenge.png',
    'https://docs.bokeh.org/static/snakebite.jpg'
],
fonts=[
    '<i>italics</i>',
    '<pre>pre</pre>',
    '<b>bold</b>',
    '<small>small</small>',
    '<del>del</del>'
]
))

TOOLTIPS = """
<div>
    <div>
        <img
            src="@imgs" height="42" alt="@imgs" width="42"
            style="float: left; margin: 0px 15px 15px 0px;"
            border="2"
        ></img>
    </div>
    <div>
        <span style="font-size: 17px; font-weight: bold;">@desc</span>
        <span style="font-size: 15px; color: #966;">[$index]</span>
    </div>
    <div>
        <span>@fonts{safe}</span>
    </div>
    <div>
        <span style="font-size: 15px;">Location</span>
        <span style="font-size: 10px; color: #696;">($x, $y)</span>
    </div>
</div>
"""

 p = figure(plot_width=400, plot_height=400, tooltips=TOOLTIPS,
       title="Mouse over the dots")

 p.circle('x', 'y', size=20, source=source)

 show(p)

The code taken from https://docs.bokeh.org/en/latest/docs/user_guide/tools.html displays


回答1:


You can use TapTool callback like in the code below. Clicking a circle displays the tooltip. Clicking elsewhere on the plot or clicking the ResetTool hides the tooltip. The TapTool callback uses the same HoverTool tooltip as in your example and you can further customise it as you wish.

See also this post which uses mini-plot as a tooltip.

This code is for Bokeh v1.0.4

from bokeh.plotting import figure, output_file, show, ColumnDataSource
from bokeh.models import TapTool, CustomJS, HoverTool, Div, Row

output_file("toolbar.html")

source = ColumnDataSource(data = dict(
x = [1, 2, 3, 3, 4],
y = [2, 5, 8, 3, 6],
desc = ['A', 'B', 'C', 'D', 'E'],
imgs = ['https://docs.bokeh.org/static/snake.jpg',
        'https://docs.bokeh.org/static/snake2.png',
        'https://dods.bokeh.org/static/snake3D.png',
        'https://docs.bokeh.org/static/snake4_TheRevenge.png',
        'https://docs.bokeh.org/static/snakebite.jpg'],
fonts = ['<i>italics</i>',
         '<pre>pre</pre>',
         '<b>bold</b>',
         '<small>small</small>',
         '<del>del</del>' ]))
TOOLTIPS = """
<div>
    <div>
        <img
            src="@imgs" height="42" alt="@imgs" width="42"
            style="float: left; margin: 0px 15px 15px 0px;"
            border="2"/>
    </div>
    <div width=60px>
        <span style="font-size: 17px; font-weight: bold;">@desc</span>
        <span style="font-size: 15px; color: #966;">[$index]</span>
    </div>
    <div>
        <span>@fonts{safe}</span>
    </div>
    <div>
        <span style="font-size: 15px;">Location</span>
        <span style="font-size: 10px; color: #696;">($x, $y)</span>
    </div>
</div> """

p = figure(plot_width = 400, plot_height = 400, x_range = (0, 6), y_range = (1, 9),
      title = "Mouse over the dots", tools = 'pan,wheel_zoom,save,reset,tap')
circles = p.circle('x', 'y', size = 20, source = source)
div = Div(text = '<div id="tooltip" style="position: absolute; display: none"></div>', name = 'tooltip')

code = '''  if (cb_data.source.selected.indices.length > 0){
                var selected_index = cb_data.source.selected.indices[0];
                var tooltip = document.getElementById("tooltip");

                tooltip.style.display = 'block';
                tooltip.style.left = Number(cb_data.geometries.sx) + Number(20) + 'px';
                tooltip.style.top = Number(cb_data.geometries.sy) - Number(20) + 'px';

                tp = tp.replace('@imgs', cb_data.source.data.imgs[selected_index]);
                tp = tp.replace('@desc', cb_data.source.data.desc[selected_index]);
                tp = tp.replace('@fonts{safe}', cb_data.source.data.fonts[selected_index]);
                tp = tp.replace('$index', selected_index);
                tp = tp.replace('$x', Math.round(cb_data.geometries.x));
                tp = tp.replace('$y', Math.round(cb_data.geometries.y));
                tooltip.innerHTML = tp;
          } '''
p.select(TapTool).callback = CustomJS(args = {'circles': circles, 'plot': p, 'tp': TOOLTIPS}, code = code)
source.selected.js_on_change('indices', CustomJS(code = 'if (cb_obj.indices.length == 0) document.getElementById("tooltip").style.display = \"none\"'))
layout = Row(p, div)
show(layout)

Result:



来源:https://stackoverflow.com/questions/54481438/fixed-hovertool-tooltips-when-taping-an-element-of-a-bokeh-plot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!