使用Bokeh ColumnDataSource作为数据源时出错,求原因及正确用法
ColumnDataSource 正确用法解析
核心错误原因
你之前的所有报错都源于两个关键误解:
source参数必须传入 ColumnDataSource实例,不能是字典、DataFrame或列表- 当指定
source后,x/y必须传入数据源中的列名字符串,而非直接提取的数组/列表
正确代码示例
1. 数据源创建(你的原有代码没问题)
import pandas as pd import numpy as np from bokeh.plotting import figure, show from bokeh.models import ColumnDataSource col_list = ['ob1','ob2','ob3','ob4','ob5'] df = pd.DataFrame(np.random.uniform(73.965,74.03,size=(25, 5)).astype(float), columns=col_list) df.reset_index(inplace=True) df = df.rename(columns = {'index':'order'}) df['order'] = df['order'] + 1 cds = ColumnDataSource(data=df)
2. 正确绘制折线图
p = figure(title='ColumnDataSource test', sizing_mode='stretch_both') # 关键:x/y传列名,source传ColumnDataSource对象 p.line(x='order', y='ob1', source=cds) show(p)
错误案例拆解
第一次报错(TypeError: unhashable type: 'list')
你传入的source=cds.data[['order', 'ob1']]是DataFrame子集,不是ColumnDataSource实例,且列表作为索引导致哈希错误。后续RuntimeError
虽然你后来把source改成了正确的ColumnDataSource,但x=cds.data['order']直接传递了数组,违反Bokeh规则:指定source后,必须通过列名字符串让Bokeh自动从数据源中提取数据。
扩展用法:同一数据源绘制多条线
利用ColumnDataSource可以高效复用数据,绘制多条折线:
p = figure(title='Multiple Lines from CDS', sizing_mode='stretch_both') p.line(x='order', y='ob1', source=cds, color='red', legend_label='ob1') p.line(x='order', y='ob2', source=cds, color='blue', legend_label='ob2') p.legend.location = 'top_left' show(p)
关键规则总结
- 两种绘图模式二选一:
- 不指定source:直接传入x/y的序列数据(如列表、数组)
- 指定source:传入ColumnDataSource实例,x/y用列名字符串
- ColumnDataSource的核心价值是统一管理数据,支持交互操作(如悬浮提示、动态更新),复杂场景下推荐使用
内容的提问来源于stack exchange,提问作者Python_Learner
相关产品推荐
相关产品推荐

