Bokeh DataTable或ColumnDataSource是否有记录数据排序顺序的属性?
解决Bokeh DataTable排序联动柱状图的问题
你说得对,ColumnDataSource本身并没有直接存储排序顺序的属性,但DataTable组件有一个关键的sorting属性,它会记录当前表格的排序状态(包括排序的字段和方向)。我们可以通过监听这个属性的变化,来同步更新柱状图的顺序。
具体来说,当用户点击表头排序时,DataTable.sorting会更新为一个列表,里面包含类似(字段名, 排序方向)的元组(比如('y', 'ascending')或('x', 'descending'))。我们可以利用这个信息重新排序数据源的数据,同时更新柱状图的x_range来匹配新的顺序。
下面是修改后的完整示例代码:
import pandas as pd from bokeh.models.sources import ColumnDataSource from bokeh.models.widgets.tables import DataTable, TableColumn from bokeh.plotting import figure from bokeh.layouts import layout from bokeh.io import curdoc df = pd.DataFrame({'x': ['a', 'b', 'c'], 'y': [1, 2, 3]}) source = ColumnDataSource(df) # 创建表格,开启表头排序功能 my_table = DataTable( source=source, columns=[TableColumn(field=x, title=x) for x in source.column_names], sortable=True ) # 创建初始柱状图 my_figure = figure(x_range=source.data['x']) my_figure.vbar(x='x', top='y', width=0.9, source=source) # 定义排序联动的回调函数 def update_plot_on_sort(attr, old, new): if not new: # 取消排序时恢复原始数据顺序 sorted_df = df.copy() else: # 获取当前排序的字段和方向 sort_col, sort_dir = new[0] sorted_df = df.sort_values(by=sort_col, ascending=(sort_dir == 'ascending')) # 更新数据源数据 source.data = sorted_df.to_dict('list') # 更新柱状图的x轴分类顺序 my_figure.x_range.factors = sorted_df['x'].tolist() # 监听DataTable的排序状态变化 my_table.on_change('sorting', update_plot_on_sort) # 布局并添加到文档 l = layout([my_table, my_figure]) curdoc().add_root(l)
几点关键说明:
- 必须确保
DataTable的sortable参数设为True,这样表头点击才会触发排序动作。 - 回调函数中我们基于原始DataFrame重新排序,避免多次排序导致的数据混乱。
- 因为你的x轴是分类类型,所以需要同步更新
x_range.factors来保证柱状图的顺序和表格一致。
这样就能实现点击表格表头排序时,柱状图的列随之重新排序的联动效果了。
内容的提问来源于stack exchange,提问作者Elliot
相关产品推荐
相关产品推荐

