使用 HoverTool() 工具时仅显示一个工具提示
Displaying only one tooltip when using the HoverTool() tool
我在Bokeh中绘制了很多点,并且我在图形的工具列表中添加了HoverTool,以便鼠标在关闭时显示鼠标的x,y
坐标到字形。
当鼠标靠近一组紧密排列在一起的字形时,我会得到与字形一样多的工具提示。我只想要一个工具提示,最接近的字形之一。这不仅仅是一个演示细节,因为对于很多点来说,结果是:
- 与情节的交互缓慢,浏览器在生成所有工具提示时卡住
- 在一个很长的工具提示中,其中相同信息的重复次数与光标附近的字形数量一样多
下面是一个示例,其中包含复制该行为的代码:
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)
我遇到了类似的问题,想出了一个使用自定义工具提示的解决方案。我在顶部插入一个样式标签,它只显示 .bk-tooltip
class 下的第一个子 div
,这是第一个工具提示。
这是一个工作示例:
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。
感谢 pst0101 的出色回答,它在 2018 年仍然有效。由于开发人员看起来不会很快达到这个目的,我想我会添加一个简短的注释说明如何使 pst 的解决方案适用于 basic/standard 工具提示 ,因为我自己进行了一些尝试和错误修改。
由于代码值一千字,这里是我自己的精简版:
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 包含一个不间断 space 的 unicode 字符串,并且 {safe} 告诉 bokeh 从我的描述字段中呈现 html(特别是换行符)是安全的。与问题无关,但很有用,因为悬停有一些破损的长文本包装行为,很多人需要处理。
上面的很好的解决方案。特别感谢克里斯布雷斯。
我在时间序列数据中遇到工具提示问题,其中数据点的数量非常多并且无法进行子采样。由于圆圈的紧密度,显示了多个工具提示。
我需要将工具提示分别添加到多个字形,这些字形对应于 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 开发人员在可用时在用户指南中包含一个代码片段。
我知道这可能是旧的,但现在有更好的方法来做到这一点。更好的意思是,此方法可以扩展到任何阈值数(如 4 个工具提示)。
所以,步骤:
定义一个 CustomJSHover。您可以在其中编写 JS 代码。此外,您还可以访问当前悬停的所有索引。在代码中,您应该设置阈值并删除其他索引(将删除本地副本)。在此之后,您应该检查是否可以在该列表中找到当前索引。如果找到,return 一个空字符串,否则 - return 一个隐藏单词的字符串(将在 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 工具提示,向主 div 添加一个将映射到我们的 CustomJSHover 的变量。让它成为y。在我们的例子中,它看起来像这样
。 ({custom} 对于映射变量是强制性的)诀窍是因为我们的 CustomJSHover 将 return 'hidden' 当索引将不在索引中,整个工具提示将隐藏。
iii)对于格式化程序,您应该添加一个从您的 var (@y) 到 CustomJSHover 的字典映射。在我们的例子中:格式化程序={'@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改成任意数字
已发布的 CSS 解决方案不适用于 Bokeh 2.2.2。以下是:
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.
网站上的嵌入式图表实现的
感谢@bachree 更新的 CSS 代码,该代码适用于 2.3.0。
使用该代码,您可以简单地添加以下行,例如在您的导入下方,到您的 jupyter notebook:
### your imports
from IPython.core.display import display, HTML
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
在撰写本文时,bokeh 方面没有任何进展,这似乎仍然是 'the way' 解决这个问题的方法。
我在Bokeh中绘制了很多点,并且我在图形的工具列表中添加了HoverTool,以便鼠标在关闭时显示鼠标的x,y
坐标到字形。
当鼠标靠近一组紧密排列在一起的字形时,我会得到与字形一样多的工具提示。我只想要一个工具提示,最接近的字形之一。这不仅仅是一个演示细节,因为对于很多点来说,结果是:
- 与情节的交互缓慢,浏览器在生成所有工具提示时卡住
- 在一个很长的工具提示中,其中相同信息的重复次数与光标附近的字形数量一样多
下面是一个示例,其中包含复制该行为的代码:
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)
我遇到了类似的问题,想出了一个使用自定义工具提示的解决方案。我在顶部插入一个样式标签,它只显示 .bk-tooltip
class 下的第一个子 div
,这是第一个工具提示。
这是一个工作示例:
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。
感谢 pst0101 的出色回答,它在 2018 年仍然有效。由于开发人员看起来不会很快达到这个目的,我想我会添加一个简短的注释说明如何使 pst 的解决方案适用于 basic/standard 工具提示 ,因为我自己进行了一些尝试和错误修改。
由于代码值一千字,这里是我自己的精简版:
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 包含一个不间断 space 的 unicode 字符串,并且 {safe} 告诉 bokeh 从我的描述字段中呈现 html(特别是换行符)是安全的。与问题无关,但很有用,因为悬停有一些破损的长文本包装行为,很多人需要处理。
上面的很好的解决方案。特别感谢克里斯布雷斯。 我在时间序列数据中遇到工具提示问题,其中数据点的数量非常多并且无法进行子采样。由于圆圈的紧密度,显示了多个工具提示。 我需要将工具提示分别添加到多个字形,这些字形对应于 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 开发人员在可用时在用户指南中包含一个代码片段。
我知道这可能是旧的,但现在有更好的方法来做到这一点。更好的意思是,此方法可以扩展到任何阈值数(如 4 个工具提示)。 所以,步骤:
定义一个 CustomJSHover。您可以在其中编写 JS 代码。此外,您还可以访问当前悬停的所有索引。在代码中,您应该设置阈值并删除其他索引(将删除本地副本)。在此之后,您应该检查是否可以在该列表中找到当前索引。如果找到,return 一个空字符串,否则 - return 一个隐藏单词的字符串(将在 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 工具提示,向主 div 添加一个将映射到我们的 CustomJSHover 的变量。让它成为y。在我们的例子中,它看起来像这样
iii)对于格式化程序,您应该添加一个从您的 var (@y) 到 CustomJSHover 的字典映射。在我们的例子中:格式化程序={'@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改成任意数字
已发布的 CSS 解决方案不适用于 Bokeh 2.2.2。以下是:
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.
网站上的嵌入式图表实现的感谢@bachree 更新的 CSS 代码,该代码适用于 2.3.0。
使用该代码,您可以简单地添加以下行,例如在您的导入下方,到您的 jupyter notebook:
### your imports
from IPython.core.display import display, HTML
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
在撰写本文时,bokeh 方面没有任何进展,这似乎仍然是 'the way' 解决这个问题的方法。