如何为Bokeh堆叠面积图添加HoverTool提示框?
给Bokeh堆叠面积图添加HoverTool提示框的解决方案
这个问题确实挺常见的——Bokeh的varea_stack虽然能快速生成堆叠面积图,但默认情况下没法直接给堆叠区域加HoverTool,因为它内部是基于原始数据计算堆叠位置的,我们需要的每个区域的上下边界值并没有直接存放在数据源里。不过有个直观的解决办法:预先计算好每一层堆叠的顶部和底部y值,然后用这些数据绘制面积图并配置HoverTool。
下面是修改后的完整代码,带详细注释:
from datetime import date from bokeh.models import ColumnDataSource, HoverTool from bokeh.plotting import figure, show # 原始数据 data = { "months": [date(2019, 5, 1), date(2019, 6, 1), date(2019, 7, 1), date(2019, 8, 1)], "dogs": [7, 5, 12, 8], "cats": [25, 20, 10, 7], } # 计算每一层堆叠的上下边界值 # Dogs层:底部是0,顶部就是自身的数值 data["dogs_bottom"] = [0] * len(data["dogs"]) data["dogs_top"] = data["dogs"] # Cats层:底部是Dogs层的顶部,顶部是Dogs+Cats的总和 data["cats_bottom"] = data["dogs"] data["cats_top"] = [d + c for d, c in zip(data["dogs"], data["cats"])] # 创建包含堆叠边界的数据源 source = ColumnDataSource(data=data) # 初始化绘图对象 p = figure( min_width=500, plot_height=300, sizing_mode="stretch_width", toolbar_location=None, x_axis_type="datetime", ) # 先绘制底层的Cats面积(堆叠图要从下往上画) p.varea( x="months", y1="cats_bottom", y2="cats_top", color="#00ff00", source=source, name="cats", # 给这个渲染器命名,方便HoverTool识别 legend_label="Cats" ) # 再绘制上层的Dogs面积 p.varea( x="months", y1="dogs_bottom", y2="dogs_top", color="#ff0000", source=source, name="dogs", # 命名对应数据源的字段 legend_label="Dogs" ) # 配置HoverTool hover = HoverTool( tooltips=[ ("日期", "@months{%F}"), ("类别", "$name"), ("当前类别数量", "@$name"), ("累计总数量", "@$name_top"), ], formatters={ "@months": "datetime", # 格式化日期显示 }, renderers=p.renderers, # 对所有面积渲染器生效 mode="vline" # 垂直悬停线,方便对齐日期点 ) # 添加HoverTool到图中 p.add_tools(hover) # 可选:点击图例可以隐藏对应层 p.legend.click_policy = "hide" show(p)
关键说明:
- 堆叠边界计算:每一层的底部是上一层的顶部,顶部是自身数值加上上一层的顶部(最底层底部为0),这样每个面积区域的范围就明确了。
- 渲染器命名:给每个
varea设置name参数,对应数据源里的字段名,HoverTool可以通过$name自动匹配当前悬停的区域,动态获取对应的数值。 - HoverTool配置:用
@$name和@$name_top可以动态调用对应层的原始数值和堆叠后的顶部数值,mode="vline"让悬停时显示垂直辅助线,更方便对应到x轴的日期点。
如果有更多堆叠层,只需要按照这个逻辑依次计算每一层的bottom和top字段即可,扩展性很强。
内容的提问来源于stack exchange,提问作者Phil Gyford
相关产品推荐
相关产品推荐

