当前位置: 首页 > 知识库问答 >
问题:

是否有保存bokeh数据表内容的方法

柳经纶
2023-03-14

我正在尝试使用bokeh数据表来显示网页中嵌入的数据。它工作得很好。

有没有办法从显示的数据表中保存表格内容?其他bokeh图有用于包括保存在内的各种功能的工具栏,但DataTable似乎没有附带。我对bokeh数据表使用的javascript或slickgrid知之甚少。想知道是否可以做到。

谢谢

编辑-我原来的问题似乎不够清楚。希望以下图片可以帮助说明:

Bokeh plot具有关联的工具栏:

但默认情况下,数据表中没有该参数,并且它也不会接受“tools”参数:

是否可以将“保存”按钮添加到数据表中,以便查看该表的人员可以下载为制表符分隔的文件或csv文件?不一定需要外观相同,但具有相同的保存功能。

共有3个答案

鲁鸿朗
2023-03-14

与我对stackoverflow问题的回答相关。下面复制了响应:

此jupyter笔记本的公共github链接:
https://github.com/surfaceowl-ai/python_visualizations/blob/master/notebooks/bokeh_save_linked_plot_data.ipynb

虚拟环境python版本:python 3.7.5
虚拟环境ipython版本:7.9.0

波基1.4.0
朱比1.0.0
努比1.17.4
熊猫0.25.3
上升5.6.0
水印2.0.2

# Generate linked plots + TABLE displaying data + save button to export cvs of selected data

from random import random

from bokeh.io import output_notebook  # prevent opening separate tab with graph
from bokeh.io import show

from bokeh.layouts import row
from bokeh.layouts import grid
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.models import Button  # for saving data
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn
from bokeh.models import HoverTool
from bokeh.plotting import figure


# create data
x = [random() for x in range(500)]
y = [random() for y in range(500)]

# create first subplot
plot_width = 400
plot_height = 400

s1 = ColumnDataSource(data=dict(x=x, y=y))
fig01 = figure(
    plot_width=plot_width,
    plot_height=plot_height,
    tools=["lasso_select", "reset", "save"],
    title="Select Here",
)
fig01.circle("x", "y", source=s1, alpha=0.6)

# create second subplot
s2 = ColumnDataSource(data=dict(x=[], y=[]))

# demo smart error msg:  `box_zoom`, vs `BoxZoomTool`
fig02 = figure(
    plot_width=400,
    plot_height=400,
    x_range=(0, 1),
    y_range=(0, 1),
    tools=["box_zoom", "wheel_zoom", "reset", "save"],
    title="Watch Here",
)

fig02.circle("x", "y", source=s2, alpha=0.6, color="firebrick")

# create dynamic table of selected points
columns = [
    TableColumn(field="x", title="X axis"),
    TableColumn(field="y", title="Y axis"),
]

table = DataTable(
    source=s2,
    columns=columns,
    width=400,
    height=600,
    sortable=True,
    selectable=True,
    editable=True,
)

# fancy javascript to link subplots
# js pushes selected points into ColumnDataSource of 2nd plot
# inspiration for this from a few sources:
# credit: https://stackoverflow.com/users/1097752/iolsmit via: https://stackoverflow.com/questions/48982260/bokeh-lasso-select-to-table-update
# credit: https://stackoverflow.com/users/8412027/joris via: https://stackoverflow.com/questions/34164587/get-selected-data-contained-within-box-select-tool-in-bokeh

s1.selected.js_on_change(
    "indices",
    CustomJS(
        args=dict(s1=s1, s2=s2, table=table),
        code="""
        var inds = cb_obj.indices;
        var d1 = s1.data;
        var d2 = s2.data;
        d2['x'] = []
        d2['y'] = []
        for (var i = 0; i < inds.length; i++) {
            d2['x'].push(d1['x'][inds[i]])
            d2['y'].push(d1['y'][inds[i]])
        }
        s2.change.emit();
        table.change.emit();

        var inds = source_data.selected.indices;
        var data = source_data.data;
        var out = "x, y\\n";
        for (i = 0; i < inds.length; i++) {
            out += data['x'][inds[i]] + "," + data['y'][inds[i]] + "\\n";
        }
        var file = new Blob([out], {type: 'text/plain'});

    """,
    ),
)

# create save button - saves selected datapoints to text file onbutton
# inspriation for this code:
# credit:  https://stackoverflow.com/questions/31824124/is-there-a-way-to-save-bokeh-data-table-content
# note: savebutton line `var out = "x, y\\n";` defines the header of the exported file, helpful to have a header for downstream processing

savebutton = Button(label="Save", button_type="success")
savebutton.callback = CustomJS(
    args=dict(source_data=s1),
    code="""
        var inds = source_data.selected.indices;
        var data = source_data.data;
        var out = "x, y\\n";
        for (i = 0; i < inds.length; i++) {
            out += data['x'][inds[i]] + "," + data['y'][inds[i]] + "\\n";
        }
        var file = new Blob([out], {type: 'text/plain'});
        var elem = window.document.createElement('a');
        elem.href = window.URL.createObjectURL(file);
        elem.download = 'selected-data.txt';
        document.body.appendChild(elem);
        elem.click();
        document.body.removeChild(elem);
        """,
)

# add Hover tool
# define what is displayed in the tooltip
tooltips = [
    ("X:", "@x"),
    ("Y:", "@y"),
    ("static text", "static text"),
]

fig02.add_tools(HoverTool(tooltips=tooltips))

# display results
# demo linked plots
# demo zooms and reset
# demo hover tool
# demo table
# demo save selected results to file

layout = grid([fig01, fig02, table, savebutton], ncols=3)

output_notebook()
show(layout)

# things to try:
# select random shape of blue dots with lasso tool in 'Select Here' graph
# only selected points appear as red dots in 'Watch Here' graph -- try zooming, saving that graph separately
# selected points also appear in the table, which is sortable
# click the 'Save' button to export a csv

# TODO:  export from Bokeh to pandas dataframe
王兴腾
2023-03-14

如果bokeh提供了一个将数据表保存/导出为csv/txt/excel文件的工具按钮,那就太好了。如果已经找到了,我还没有在文档中找到它。

同时,一个可能的答案是使用本机javascript将js数组(位于bokeh数据表下方)导出到CSV。这里和这里都有描述。

添加:bokeh有使用js的回调。这里有一个简单的描述。仍在阅读。。。

编辑:现在可能有一段时间了,但我刚刚注意到Bokeh网站上的一个从数据表中保存csv的示例。

司业
2023-03-14

2021更新:调整后的代码适用于python 3.8和bokeh 2.2.3

对于那些在bokeh网站上调整或查找示例有困难或只是非常懒惰的人,下面的代码可以完成最少的工作:

from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models.widgets import Button
from bokeh.io import show
import os

source = ColumnDataSource({'list1':[0,1,2,3],'list2':[4,5,6,7]})
button = Button(label="Download", button_type="success")
button.js_on_click(CustomJS(args=dict(source=source),code=open(os.path.join(os.path.dirname(__file__),"download.js")).read()))
show(button)

文件download.js:

function table_to_csv(source) {
    const columns = Object.keys(source.data)
    const nrows = source.get_length()
    const lines = [columns.join(',')]

    for (let i = 0; i < nrows; i++) {
        let row = [];
        for (let j = 0; j < columns.length; j++) {
            const column = columns[j]
            row.push(source.data[column][i].toString())
        }
        lines.push(row.join(','))
    }
    return lines.join('\n').concat('\n')
}


const filename = 'data_result.csv'
const filetext = table_to_csv(source)
const blob = new Blob([filetext], { type: 'text/csv;charset=utf-8;' })

//addresses IE
if (navigator.msSaveBlob) {
    navigator.msSaveBlob(blob, filename)
} else {
    const link = document.createElement('a')
    link.href = URL.createObjectURL(blob)
    link.download = filename
    link.target = '_blank'
    link.style.visibility = 'hidden'
    link.dispatchEvent(new MouseEvent('click'))
}
 类似资料:
  • 我有一张表,贴上: 当我插入一行内容超过15k个单词时,我的数据库只保存了10k个单词,而我丢失了5k个单词。 我如何修复此问题? 我正在使用MySQL和PHP框架Laravel 5.1

  • 保存内容 能将已登录之频道的内容(项目),保存至Memory Stick™或主机内存。若要保存,可选择下述方法进行。 (1) 只选择1个项目保存 挑选想保存的项目后,选择选项选单的[保存]。 (2) 整合保存频道内的数个项目 挑选已保存的频道后,选择选项选单的[保存]。 (3) 选择数个频道后保存项目 挑选频道后,选择选项选单的[保存]。 提示 希望选择(2)或(3)时,能保存之项目数量可能因(设

  • 我使用一个java jdbc应用程序从DB中获取大约500,000条记录。使用的数据库是Oracle。当每一行被取出时,我就将数据写入文件。由于获取整个数据需要大约一个小时,所以我尝试增加结果集的获取大小。我在多个链接中看到,在增加读取大小的同时,应该小心内存消耗。增加读取大小实际上会增加jvm使用的堆内存吗?< br >假设提取大小为10,程序查询总共返回100行。在第一次提取期间,结果集包含1

  • 问题内容: 该MMAP文件说,下面讲的标志MAP_NORESERVE。 不要为该映射保留交换空间。当保留交换空间时,可以保证可以修改映射。如果没有保留交换空间,则在没有物理内存可用的情况下,可能会在写入时获得SIGSEGV。 我真正想要的只是保留虚拟内存地址,而没有分配实际的物理内存。可以使用MAP_NORESERVE的mmap来完成此操作吗?如果我想使用任何物理内存,我将在MAP_NORESER

  • 问题内容: 我上了一堂课,想跟踪学生的统计数据。我打算稍后制作一个GUI来处理这些数据。 我的主要问题是:保存和以后检索此数据的最佳方法是什么? 我已经读过关于pickle和JSON的文章,但是我并没有真正了解它们的工作方式(尤其是关于它们如何保存数据的信息,例如哪种格式和位置)。 问题答案: 对于持久性数据(存储有关学生的信息),数据库是一个不错的选择。如前所述,Python附带了Sqlite3

  • 本文向大家介绍Android实现EditText内容保存为Bitmap的方法,包括了Android实现EditText内容保存为Bitmap的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Android实现EditText内容保存为Bitmap的方法。分享给大家供大家参考,具体如下: 主要代码如下: 更多关于Android控件相关内容感兴趣的读者可查看本站专题:《Android控件用