如何用Bokeh实现嵌套字典表格展示并去除自动生成多余表格
解决Bokeh表格绘制的两个问题:数据格式错误与多余表格
一、初始代码的报错原因与修复
你最初碰到的ValueError: expected an element of ColumnData(String, Seq(Any)),核心原因是Bokeh的ColumnDataSource只接受扁平化的键值对结构,每个键对应的值必须是等长的序列(比如列表、numpy数组),而你传入的嵌套字典完全不符合这个要求。
要把嵌套字典转换成符合规范的格式,我们需要把每个position作为表格的一行,x/y/z作为列,正确的数据转换和代码实现如下:
from bokeh.models import ColumnDataSource from bokeh.models.widgets import DataTable, TableColumn from bokeh.layouts import column from bokeh.io import show def testTable(): # 原始嵌套字典数据 raw_data = {'position1': {'x': 0, 'y': 0, 'z': 0}, 'position2': {'x': 1.1, 'y': 2.3, 'z': 3}, 'position3': {'x': 2.9, 'y': 4.3, 'z': 3.1}} # 转换为ColumnDataSource要求的扁平化序列格式 data = { 'InitPosition': list(raw_data.keys()), 'x': [pos['x'] for pos in raw_data.values()], 'y': [pos['y'] for pos in raw_data.values()], 'z': [pos['z'] for pos in raw_data.values()] } source = ColumnDataSource(data) columns = [ TableColumn(field="InitPosition", title="Init Position"), TableColumn(field="x", title="x"), TableColumn(field="y", title="y"), TableColumn(field="z", title="z") ] data_table = DataTable(source=source, columns=columns, width=400, height=280) # 直接用column布局即可,无需嵌套多余容器 plot = column(data_table) show(plot) if __name__ == '__main__': testTable()
二、重构后多余表格的解决方法
你重构后出现多余表格,问题出在布局容器重复嵌套:widgetbox本身是用来包裹小部件的布局容器,而你又把它放到了column里,在部分Bokeh版本中会导致重复渲染容器边框,看起来像是多出了一个表格。
解决起来很简单:
- 推荐直接使用
column(data_table)作为布局(widgetbox在Bokeh 2.0+版本已经被官方弃用,更推荐用column/row替代) - 或者单独使用
widgetbox(data_table),不要嵌套到column中
另外注意你重构后的代码里,x/y/z的数值对应错误了(比如position1的x应该是0,但你写的x列表是[0,0,0]),上面的修复代码已经帮你修正了这个数据错误。
关键知识点总结
ColumnDataSource的核心规则:每个键对应的值必须是长度相同的序列,绝对不能用嵌套字典- 布局容器不要重复嵌套,避免出现多余的渲染元素
- 新版本Bokeh优先使用
column/row替代已弃用的widgetbox
内容的提问来源于stack exchange,提问作者toti08
相关产品推荐
相关产品推荐

