保存 Bokeh 仪表板(独立),其中包含内部制作的所有数据

Posted

技术标签:

【中文标题】保存 Bokeh 仪表板(独立),其中包含内部制作的所有数据【英文标题】:Saving Bokeh dashdoard (standalone) with all the data made inside 【发布时间】:2020-07-12 00:03:43 【问题描述】:

有没有什么方法可以在编辑后保存 Bokeh 仪表盘?

例如,我已经加载了我的仪表板,创建了一些图并保存了它们(最后一个选项卡)。然后我想将我的“进度”保存到 .html 文件中,这样我就不必在每次初始化脚本后都再次执行所有这些操作。

这是我的仪表板的屏幕截图:

谢谢!

【问题讨论】:

您希望能够只看它还是继续您上次停下的工作?您的屏幕截图似乎使用了 Jupyter 笔记本 - 您是否使用任何带有 Bokeh 的 Python 代码或所有内容都使用 javascript 完全基于js。我在 Jupyter Notebook 中使用它而不启动服务器。之后我希望能够使用它来添加一些新图形或进行另一个数据查询。所以,我想它必须在 html 中。 我发现,在其中进行更新后保存 .html 文件不会更改源文件。我尝试将仪表板下载为 .html,然后在浏览器中打开它,进行更改,然后将其保存到我的硬盘中。之后,我得到了与第一步下载的文件相同的文件。这意味着在进行更改后将仪表板保存在 .html 中不起作用。我必须找到另一个解决方案。 是的,HTML 文件只存储布局。所有其他状态都存储在 JavaScript 内存中。我正在尝试想出一个解决方案 - 这应该是可能的。 嗯,可以使用Bokeh.documents[0].to_json_string() 保存文档并使用Bokeh.embed.add_document_standalone 加载它。但在我的情况下,这些情节并没有呈现任何内容。 【参考方案1】:

所以解决办法是: 1将您的散景文档(您的整个仪表板)转换为 .json 并将其下载为文件。

例如,您通过单击按钮来完成。

#  creating button
download_json = Button(label="Download json", width=70)
# callback
download_json_func = CustomJS(args=dict(source=source_fill_groupby),code="""
function saveText(text, filename)
var a = document.createElement('a');
a.setAttribute('href', 'data:text/plain;charset=utf-8,'+encodeURIComponent(text));
a.setAttribute('download', filename);
a.click()

var obj = Bokeh.documents[0].to_json_string();
saveText( JSON.stringify(obj), "filename.json" );
""")
# assigning callback to the button
download_json.js_on_event(ButtonClick, download_json_func)

2下载文件后,您需要在 Jupyter 笔记本的下一个单元格中恢复它。假设应该有 FileInput-widget,这样我们就可以上传我们的文件,它会出现在 div-block 中。

from bokeh.models.widgets import FileInput
# creating div where our saved dashboard will be shown
div = Div(text='<div id="document-container"></div>', width=500, height=500)
# adding widget
l = FileInput(accept='.json')
# callback
l.js_on_change('value', CustomJS(code="""\
const Document = Bokeh.require('document/document');
// uploaded .json-file  
const data = JSON.parse(atob(cb_obj.value));            
const doc = Document.from_json_string(data);
// dashboard to show
Bokeh.embed.add_document_standalone(doc, document.getElementById('document-container'), [], true);                                     
cb_obj.disabled = true;
"""))

show(column(l, div))

它仍然存在一些问题 - 如果您进行新的查询和创建新的绘图,它不会正确显示 ciryllic,并且绘图不会从最后一个保存文档后更新其范围。将绘图保存到最后一个选项卡也存在一些问题 - 它不像在 Bokeh 中那样工作。但至少你可以在你的研究中保存你的“进步”。

更新1。要正确显示西里尔字母,您应该使用 FileInput 的下一个回调:

    l.js_on_change('value', CustomJS(code="""
function b64DecodeUnicode(str) 
    // Going backwards: from bytestream, to percent-encoding, to original string.
    return decodeURIComponent(atob(str).split('').map(function(c) 
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    ).join(''));


const Document = Bokeh.require('document/document');
const data = JSON.parse(b64DecodeUnicode(cb_obj.value));
const doc = Document.from_json_string(data);
Bokeh.embed.add_document_standalone(doc, document.getElementById('document-container1'), [], true);
cb_obj.disabled = true;
"""))

【讨论】:

以上是关于保存 Bokeh 仪表板(独立),其中包含内部制作的所有数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Bokeh 仪表板中显示和更新打印语句列表?

使用 Python 的 Bokeh 和 Folium 模块创建的仪表板/地图是不是安全?数据是不是上传到任何外部服务器?

将小部件与 pandas_bokeh 结合起来;收到“ValueError”消息

Bokeh 0.12.2rc1 发布,Python 交互式可视化库

带有 AjaxDataSource 的 Bokeh DataTable 未获取或更新

Python 和 Bokeh 上的聚类;选择允许用户更改聚类算法的小部件