如何重新打开Bokeh HTML文件并恢复所有图表的上次缩放状态?
实现Bokeh图表缩放状态的持久化
要让Bokeh生成的多图表HTML页面,在关闭后重新打开时自动恢复之前的缩放级别,核心是利用浏览器的localStorage存储图表范围状态,再在页面加载时读取并恢复。以下是具体实现方案:
实现思路
- 给每个图表设置唯一ID,用于关联存储的状态
- 添加JavaScript回调,监听图表的范围变化事件,将当前x、y轴范围保存到
localStorage - 页面加载完成时,从
localStorage读取历史状态,恢复到对应图表上
修改后的示例代码
import numpy as np from bokeh.io import save from bokeh.layouts import gridplot from bokeh.plotting import figure x = np.linspace(0, 4 * np.pi, 100) y = np.sin(x) TOOLS = "pan,wheel_zoom,box_zoom,reset,save,box_select" # 给每个图表设置唯一ID,用于后续状态关联 p1 = figure(title="Legend Example", tools=TOOLS, id="plot-1") p1.circle(x, y, legend_label="sin(x)") p1.circle(x, 2 * y, legend_label="2*sin(x)", color="orange") p1.circle(x, 3 * y, legend_label="3*sin(x)", color="green") p1.legend.title = "Markers" p2 = figure(title="Another Legend Example", tools=TOOLS, id="plot-2") p2.circle(x, y, legend_label="sin(x)") p2.line(x, y, legend_label="sin(x)") p2.line( x, 2 * y, legend_label="2*sin(x)", line_dash=(4, 4), line_color="orange", line_width=2, ) p2.square(x, 3 * y, legend_label="3*sin(x)", fill_color=None, line_color="green") p2.line(x, 3 * y, legend_label="3*sin(x)", line_color="green") p2.legend.title = "Lines" p2.x_range = p1.x_range # 自定义JS:处理状态保存与恢复 persist_zoom_js = """ // 保存单个图表的范围状态到localStorage function savePlotRange(plot) { const rangeData = { x_start: plot.x_range.start, x_end: plot.x_range.end, y_start: plot.y_range.start, y_end: plot.y_range.end }; localStorage.setItem(`bokeh-zoom-${plot.id}`, JSON.stringify(rangeData)); } // 页面加载时恢复图表范围 function restorePlotRange(plot) { const savedData = localStorage.getItem(`bokeh-zoom-${plot.id}`); if (savedData) { const rangeData = JSON.parse(savedData); plot.x_range.start = rangeData.x_start; plot.x_range.end = rangeData.x_end; plot.y_range.start = rangeData.y_start; plot.y_range.end = rangeData.y_end; } } // 遍历所有图表,绑定监听与恢复逻辑 document.addEventListener('DOMContentLoaded', function() { const plotElements = document.querySelectorAll('.bk-root .bk-plot'); plotElements.forEach(el => { const plot = Bokeh.index[el.id].model; // 监听范围变化,实时保存 plot.x_range.change.connect(() => savePlotRange(plot)); plot.y_range.change.connect(() => savePlotRange(plot)); // 页面加载时恢复状态 restorePlotRange(plot); }); }); """ # 保存HTML时注入自定义JS save( gridplot([p1, p2], ncols=2, width=400, height=400), extra_script=persist_zoom_js )
注意事项
- 状态存储在当前浏览器的
localStorage中,换浏览器或清除缓存后会丢失 - 若多个图表共享范围(如示例中p2与p1共享x轴范围),共享的范围会被同步保存和恢复
- 点击图表的
reset按钮后,重置后的范围会自动覆盖之前存储的状态
内容的提问来源于stack exchange,提问作者aura
相关产品推荐
相关产品推荐

