使用HoverTool()工具时仅显示一个工具提示

时间:2016-04-05 18:44:18

标签: python tooltip bokeh

我在Bokeh中绘制了很多点,并且我已将HoverTool添加到图的工具列表中,以便鼠标在接近a时显示鼠标的x,y坐标字形。

当鼠标接近紧密堆积在一起的一组字形时,我会得到与字形一样多的工具提示。我只想要一个工具提示,一个最接近的字形。这不仅仅是一个演示细节,因为这会产生很多分数:

  • 与情节的交互缓慢,浏览器在生成所有工具提示时卡住
  • 在一个很长的工具提示中,重复相同的信息的次数与光标接近的次数一样多

下面是一个示例,其中包含复制行为的代码: enter image description here

import numpy.random
from bokeh.plotting import figure, output_notebook, show
from bokeh.models import HoverTool
output_notebook()

hover = HoverTool()
hover.tooltips = [("(x,y)", "($x, $y)")]

x = numpy.random.randn(500)
y = numpy.random.randn(500)

p = figure(tools=[hover])
p.circle(x,y, color='red', size=14, alpha=0.4)

show(p)

6 个答案:

答案 0 :(得分:5)

我遇到了类似的问题,并提出了使用自定义工具提示的解决方案。我在顶部插入一个样式标记,只显示div类下的第一个子.bk-tooltip,这是第一个工具提示。

这是一个有效的例子:

from bokeh.plotting import figure, show
from bokeh.models import HoverTool, Range1d

custom_hover = HoverTool()

custom_hover.tooltips = """
    <style>
        .bk-tooltip>div:not(:first-child) {display:none;}
    </style>

    <b>X: </b> @x <br>
    <b>Y: </b> @y
"""

p = figure(tools=[custom_hover]) #Custom behavior
#p = figure(tools=['hover'])  #Default behavior 

p.circle(x=[0.75,0.75,1.25,1.25], y=[0.75,1.25,0.75,1.25], size=230, color='red', fill_alpha=0.2)
p.y_range = Range1d(0,2)
p.x_range = Range1d(0,2)

show(p)

这是一种hacky解决方案,但它适用于Safari,Firefox和Chrome。我认为他们会出现更长期的solution soon

答案 1 :(得分:2)

在Bokeh 2.2.2中,发布的CSS解决方案不适用于我。做了以下事情:

    div.bk-tooltip.bk-right>div.bk>div:not(:first-child) {
        display:none !important;
    }
    div.bk-tooltip.bk-left>div.bk>div:not(:first-child) {
        display:none !important;
    }

这不是最优雅的解决方案,但它以垂直堆叠的40个工具提示结束了我的挫败感。这是通过具有自定义CSS的网站上的嵌入式图表实现的。

答案 2 :(得分:1)

对pst0101表示了很好的答复,该答复在2018年仍然有效。由于开发人员看起来他们很快不会再接触到此,我想我会在此作一下简短说明pst针对基本/标准工具提示的解决方案,因为我自己修改该代码花了一些试验和错误。

由于代码值一千字,所以这是我自己的精简版本:

hoverToolTip = [
        ("Item" + nbs + "Number/s", "@{ItemNumber}"),
        ("Description/s", "@{Description}{safe}"),
        ("Virtual" + nbs + "Item", """@{IsVirtual}
        <style>
            .bk-tooltip>div:not(:first-child) {display:none;}
        </style>""")
]

hover = HoverTool(tooltips=hoverToolTip)

nbs包含一个不间断空格的unicode字符串,{safe}告诉bokeh从我的​​描述字段中呈现html(特别是换行符)是安全的。与该问题无关,但很有用,因为悬停具有一些带有长文本的折行行为,许多人需要处理。

答案 3 :(得分:1)

感谢@bachree 更新的 CSS 代码,该代码适用于 2.3.0。
使用该代码,您只需添加以下行,例如在您的导入下方,到您的 jupyter 笔记本:

### your imports
import numpy.random
from bokeh.plotting import figure, output_notebook, show
from bokeh.models import HoverTool
output_notebook()
### end of imports

# fix bokeh showing multiple values on hover in notebooks
display(HTML("""
<style>
    div.bk-tooltip.bk-right>div.bk>div:not(:first-child) {
        display:none !important;
    }
    div.bk-tooltip.bk-left>div.bk>div:not(:first-child) {
        display:none !important;
    }
</style>
"""))

### your code

在撰写本文时,散景方面没有任何进展,这似乎仍然是解决此问题的“方法”。

答案 4 :(得分:0)

上述出色的解决方案。特别感谢Chris Brace。 我在时间序列数据中使用工具提示时遇到了问题,其中数据点的数量非常多,无法进行二次采样。由于圆的紧密性,显示了多个工具提示。 我需要将工具提示分别添加到对应于pandas DataFrame中特定列的多个字形。因此,我从Chris Brace扩展了解决方案,如下所示(应用程序要求在执行过程中动态选择列名;不幸的是,在此处很难提供完整的代码,但即使这个子集也可以帮助某人):

renderer = data_plot.circle(x=my_x_axis_col_name, y=my_y_axis_col_name, source=<my_data_source>, size=2)
hover_var = '@'+my_y_axis_col_name+"<style>.bk-tooltip>div:not(:first-child) {display:none;}</style>"
hover = HoverTool(renderers=[renderer], tooltips=[(my_y_axis_col_name, hover_var)])

在Bokeh的未来版本中有望有更好的解决方案。对Bokeh开发人员的一个温柔的要求是,在可用的情况下,在用户指南中也包含一个代码段。

答案 5 :(得分:0)

我知道这可能已经很老了,但是现在有了更好的方法。更好的是,我的意思是该方法可以扩展到任何阈值数(例如4个工具提示)。 因此,步骤如下:

  1. 定义 CustomJSHover 。您可以在其中编写JS代码。此外,您可以访问当前悬停的所有索引。在代码中,您应该设置阈值并删除其他索引(将删除本地副本)。之后,您应该检查是否可以在该列表中找到当前索引。如果找到,则返回一个空字符串,否则-返回一个带有隐藏单词的字符串(将在html解析期间使用)

     custom_hov = CustomJSHover(code="""
         special_vars.indices = special_vars.indices.slice(0,4)
         if (special_vars.indices.indexOf(special_vars.index) >= 0)
         {
             return " "
         }
         else
         {
             return " hidden "
         }
     """)
    

i)在您的绘图中也添加一个 HoverTool ,并定义html工具提示+定义格式器。
ii)对于html工具提示,在main div中添加一个变量,该变量将映射到我们的CustomJSHover。让它成为y。在我们的情况下,它看起来像这样的

。 (对于映射的变量,{custom}是必需的)技巧是,由于当索引不在索引中时,我们的 CustomJSHover 将返回' hidden ',因此整个工具提示将变为隐藏。

iii)对于格式化程序,您应该添加一个从var(@y)到 CustomJSHover 的字典映射。在我们的例子中:formatters = {'@ y':custom_hov}

figure.add_tools(HoverTool(tooltips=("""  
<div @y{custom}>
    <div>
        <img src='@image' alt='@image' style='float: top; width:128px;height:128px; margin: 5px 5px 5px 5px'/>
    </div>
    <div>
        <span style='font-size: 16px; color: #224499'>Some text</span>
        <span style='font-size: 18px'>@dataFrameText</span>
    </div>
</div>
"""), formatters={'@y':custom_hov}))

就是这样。现在,将仅显示4个工具提示。您可以将4更改为任意数字