Bokeh共享图例双图表:click_policy点击隐藏功能失效求助
实现Bokeh双图表共享可点击隐藏的图例
要实现单个图例控制两个图表的显示/隐藏,核心是让所有需要联动的渲染器(Renderer)归属到同一个图例所在的图表中,同时隐藏该图表的其他视觉元素,只保留图例。以下是修正后的完整代码:
from bokeh.plotting import figure, row, gridplot from bokeh.models import ColumnDataSource, Legend, LegendItem, CDSView, IndexFilter import pandas as pd import numpy as np # 模拟测试数据(可替换为你的实际DataFrame) np.random.seed(42) dates = pd.date_range(start='2023-01-01', periods=100) data = pd.DataFrame({ 'timestamp': dates, 'col1': np.random.randn(100).cumsum(), 'col2': np.random.randn(100).cumsum(), 'col3': np.random.randn(100).cumsum() }) CUSTOM = ['#ff0000', '#00ff00', '#0000ff'] # 主数据源 source = ColumnDataSource(data) # 创建两个主图表 p1 = figure(x_axis_type='datetime', title='时序图', height=430, width=900, y_minor_ticks=5) hist = figure(title='分布直方图', x_axis_label='数值', y_axis_label='频次', height=430, width=200) # 存储所有渲染器和图例项 renderers = [] legend_items = [] # 为每一列添加对应的两个图表元素 for i, col in enumerate(data.columns[1:]): # 时序图的circle circle = p1.circle(x='timestamp', y=col, size=3, color=CUSTOM[i], alpha=0.8, source=source) # 直方图的quad:基于当前列的分布数据构建 counts, bins = np.histogram(data[col], bins=10) hist_source = ColumnDataSource({ 'top': counts, 'bottom': [0]*len(counts), 'left': bins[:-1], 'right': bins[1:] }) quad = hist.quad(top='top', bottom='bottom', left='left', right='right', source=hist_source, color=CUSTOM[i], alpha=0.8) # 将同一列的两个渲染器关联到同一个图例项 legend_items.append(LegendItem(label=col, renderers=[circle, quad])) # 收集所有渲染器 renderers.extend([circle, quad]) # 创建隐藏的dummy图表,仅用于承载图例 dum_fig = figure(width=0, height=0, outline_line_alpha=0, toolbar_location=None) # 隐藏所有不需要的元素 for elem in dum_fig.grid + dum_fig.axis: elem.visible = False # 将所有渲染器添加到dummy图中 dum_fig.renderers += renderers # 添加图例并设置点击策略 legend = Legend(items=legend_items, location='bottom_center', orientation='horizontal', ncols=3) legend.click_policy = 'hide' dum_fig.add_layout(legend, 'below') # 组合图表:主图表横向排列,下方放置共享图例 main_row = row(p1, hist) final_layout = gridplot([[main_row], [dum_fig]], toolbar_location=None) # 显示图表(Jupyter环境中执行) # from bokeh.io import show # show(final_layout)
关键修正点说明:
- 渲染器关联逻辑:在循环中为每一列的两个渲染器(时序图的circle、直方图的quad)创建对应的
LegendItem,确保图例项与两个图表的元素一一绑定。 - Dummy图表优化:将dummy图的宽高设为0,彻底隐藏图表本体,仅保留下方的图例;同时将所有需要联动的渲染器添加到该图中,这样图例的点击操作会同步控制两个主图的对应元素。
- 数据源适配:修复了原代码中直方图数据源为空的问题,根据每列数据动态生成直方图的统计数据,保证图表能正常显示。
- 布局调整:用
gridplot将主图表行和图例行垂直排列,保证图例在两个主图的下方,布局更合理。
内容的提问来源于stack exchange,提问作者Sara.SP92
相关产品推荐
相关产品推荐

