如何用Bokeh的autoload_scripts固定JavaScript ID,实现免改HTML更新图表?
解决Bokeh autoload_scripts生成随机ID的问题
嘿,我刚接触Bokeh的时候也踩过这个坑!给你两个最实用的解决方案,帮你摆脱手动改HTML的麻烦:
方案一:指定固定的target_id(最直接)
autoload_script函数其实支持传入target_id参数,你可以提前在HTML里定义一个固定ID的容器,然后让Bokeh每次都把图表渲染到这个容器里,完全不用改HTML!
步骤:
- 先在你的HTML里加一个固定ID的div:
<div id="daily-chart-container"></div>
- 在Python代码里生成脚本时指定这个target_id:
from bokeh.embed import autoload_script from bokeh.resources import CDN from bokeh.plotting import figure # 生成你的图表(这里用示例figure代替) p = figure(title="每日更新图表") p.line([1,2,3], [4,5,6]) # 指定固定的target_id,和HTML里的div ID对应 script = autoload_script(p, resources=CDN, target_id="daily-chart-container") # 把生成的script保存到一个单独的JS文件,比如chart.js with open("chart.js", "w") as f: f.write(script)
- 在HTML里引用这个JS文件:
<script src="chart.js"></script>
这样每次你更新图表并重新生成chart.js后,只要刷新网页,新图表就会自动渲染到固定ID的容器里,完全不用碰HTML文件!
方案二:用components手动控制ID(更灵活)
如果autoload_script的方式对你来说不够灵活,你可以用components函数拆分出脚本和容器代码,手动固定容器ID:
步骤:
- Python代码里生成脚本和容器:
from bokeh.embed import components from bokeh.resources import CDN from bokeh.plotting import figure p = figure(title="每日更新图表") p.line([1,2,3], [4,5,6]) # 生成脚本和容器代码,wrap_script=False避免自动包裹 script, div = components(p, wrap_script=False) # 手动替换容器的ID为固定值 fixed_div = div.replace('<div class="bk-root" id="', '<div class="bk-root" id="daily-chart-container"') # 保存脚本到chart.js with open("chart.js", "w") as f: f.write(script)
- HTML里直接写固定ID的容器(或者把fixed_div的内容直接写在HTML里):
<div class="bk-root" id="daily-chart-container" data-root-id="1"></div> <script src="chart.js"></script> <script src="https://cdn.bokeh.org/bokeh/release/bokeh-3.3.4.min.js"></script> <link rel="stylesheet" href="https://cdn.bokeh.org/bokeh/release/bokeh-3.3.4.min.css">
这种方式适合你需要自定义容器样式或者额外控制渲染逻辑的场景。
额外提示
- 记得每次更新图表后,要覆盖掉旧的
chart.js文件,这样网页加载的就是最新的脚本。 - 如果怕浏览器缓存旧脚本,可以给JS文件加个版本号参数,比如
<script src="chart.js?v=20240520"></script>,每次更新就改一下版本号。
内容的提问来源于stack exchange,提问作者nicway
相关产品推荐
相关产品推荐

