如何让Bokeh multi_line的HoverTool提示框显示所有点坐标?
解决Bokeh Multi-Line HoverTool显示所有点坐标的问题
嘿,我来帮你搞定这个Bokeh的hover提示框问题!你之前的代码里直接用@xs和@ys的话,HoverTool只会把整个坐标列表一股脑显示出来(比如[1,3,2]),而不是我们想要的逐个点的坐标对。下面我给你两种可行的解决方案,你可以根据需求选:
方法1:提前生成坐标对字符串(简单直接)
这种方法是把每条线的所有坐标对提前格式化成字符串,然后让HoverTool直接读取这个字段显示:
from bokeh.plotting import figure, output_file, show from bokeh.models import ColumnDataSource, HoverTool output_file("multi_line_hover.html") # 原始的多线数据 plot_data = dict( xs=[[1, 3, 2], [3, 4, 6, 6]], ys=[[2, 1, 4], [4, 7, 8, 5]], colors=["firebrick", "navy"], alphas=[0.8, 0.3], line_names=["Line 1", "Line 2"] # 给每条线加个名字方便识别 ) # 给每条线生成所有坐标对的字符串(用<br>换行显示) plot_data["all_coords"] = [ "<br>".join([f"({x}, {y})" for x, y in zip(xs, ys)]) for xs, ys in zip(plot_data["xs"], plot_data["ys"]) ] # 创建数据源 dsource = ColumnDataSource(plot_data) # 创建绘图对象 p = figure(title="Multi-Line with Full Coordinate Hover", tools="pan,zoom,reset") # 绘制multi_line multi_line = p.multi_line( xs="xs", ys="ys", color="colors", alpha="alphas", source=dsource ) # 配置HoverTool:悬停在线上时显示线名和所有坐标 hover = HoverTool( renderers=[multi_line], # 指定只对multi_line生效 tooltips=[ ("Line Name", "@line_names"), ("All Coordinates", "@all_coords"), ] ) p.add_tools(hover) show(p)
方法2:用自定义JS模板动态生成坐标(更灵活)
如果不想提前处理字符串,可以用Bokeh的模板语法,直接在tooltip里遍历xs和ys列表生成坐标对:
from bokeh.plotting import figure, output_file, show from bokeh.models import ColumnDataSource, HoverTool output_file("multi_line_hover_dynamic.html") plot_data = dict( xs=[[1, 3, 2], [3, 4, 6, 6]], ys=[[2, 1, 4], [4, 7, 8, 5]], colors=["firebrick", "navy"], alphas=[0.8, 0.3], line_names=["Line 1", "Line 2"] ) dsource = ColumnDataSource(plot_data) p = figure(title="Multi-Line with Dynamic Coordinate Hover", tools="pan,zoom,reset") multi_line = p.multi_line( xs="xs", ys="ys", color="colors", alpha="alphas", source=dsource ) # 用模板语法遍历坐标列表 hover = HoverTool( renderers=[multi_line], tooltips=""" <div style="font-size: 14px;"> <span style="color: @colors;">@line_names</span> </div> <div style="margin-top: 5px;"> <span>All Coordinates:</span> <ul style="margin: 5px 0 0 15px; padding: 0;"> {% for (x, y) in zip(xs, ys) %} <li>({{ x }}, {{ y }})</li> {% endfor %} </ul> </div> """, formatters={ "xs": "printf", "ys": "printf", } ) p.add_tools(hover) show(p)
关键说明:
- 两种方法都需要确保HoverTool的
renderers参数指定为我们创建的multi_line对象,这样hover只会对多线生效,不会干扰其他元素。 - 第一种方法适合数据量不大的场景,提前处理好字符串更省心;第二种方法更灵活,适合需要动态调整显示格式的情况。
内容的提问来源于stack exchange,提问作者Parikshit Bhinde
相关产品推荐
相关产品推荐

