Bokeh数据可视化:数据源与数据处理完全指南
概述
在Bokeh数据可视化项目中,数据是构建图表的基础。本文将全面介绍Bokeh中处理数据的各种方法,从简单的Python列表到高级的数据转换和过滤技术。
基础数据输入方式
使用Python列表
最直接的方式是使用Python列表传递数据:
from bokeh.plotting import figure
x_values = [1, 2, 3, 4, 5]
y_values = [6, 7, 2, 3, 6]
p = figure()
p.scatter(x=x_values, y=y_values)
这种方式简单直接,适合快速原型开发和小数据集。
使用NumPy数组
对于科学计算场景,Bokeh完美支持NumPy数据结构:
import numpy as np
from bokeh.plotting import figure
x = [1, 2, 3, 4, 5]
random = np.random.standard_normal(5)
cosine = np.cos(x)
p = figure()
p.scatter(x=x, y=random)
p.line(x=x, y=cosine)
NumPy的高性能数组运算与Bokeh结合,可以高效处理大规模数据可视化。
核心数据结构:ColumnDataSource
基本概念
ColumnDataSource(CDS)是Bokeh的核心数据结构,它为图表提供数据支持。理解CDS是掌握Bokeh高级功能的关键。
创建ColumnDataSource
from bokeh.models import ColumnDataSource
data = {'x_values': [1, 2, 3, 4, 5],
'y_values': [6, 7, 2, 3, 6]}
source = ColumnDataSource(data=data)
重要提示:CDS中所有列的长度必须一致,否则会报错。
使用CDS绘制图表
p = figure()
p.scatter(x='x_values', y='y_values', source=source)
通过指定列名和源数据,可以创建基于CDS的图表。
数据修改与更新
添加新列:
source.data["new_column"] = [8, 1, 4, 7, 3]
完全替换数据:
source.data = new_dict
注意:修改列长度时必须替换整个数据字典。
与数据框架集成
使用Pandas DataFrame
source = ColumnDataSource(df)
Bokeh会自动处理DataFrame的列名和索引:
- 命名索引会保留为单独列
- 未命名索引会命名为"index"或"level_0"
处理多级索引
对于MultiIndex DataFrame,Bokeh会扁平化处理:
- 索引转换为元组列
- 列名用下划线连接
使用GroupBy对象
group = df.groupby('year')
source = ColumnDataSource(group)
这会自动计算各组的统计量(mean, count等),列名格式为"原列名_统计量"。
高级数据操作
数据流式更新
source.stream(new_data, rollover=1000)
流式更新只发送新数据,适合实时可视化场景。rollover参数控制保留的数据量。
数据局部更新
source.patch({
'column1': [(0, new_value1), (1, new_value2)],
'column2': [(slice(2,5), [v1, v2, v3])]
})
局部更新只修改指定数据点,效率更高。
数据转换技术
客户端颜色映射
Bokeh提供三种颜色映射方式:
- 线性映射(linear_cmap)
- 对数映射(log_cmap)
- 均衡直方图映射(eqhist_cmap)
from bokeh.transform import linear_cmap
fill_color = linear_cmap('counts', 'Viridis256', min=0, max=10)
分类数据标记映射
from bokeh.transform import factor_mark
markers = factor_mark('species', ['circle', 'square', 'diamond'], species_list)
自定义JS转换
from bokeh.models import CustomJSTransform
custom_js = """
const norm = new Array(xs.length);
for (let i = 0; i < xs.length; i++) {
norm[i] = xs[i] / xs[0];
}
return norm;
"""
normalize = CustomJSTransform(v_func=custom_js)
数据过滤技术
基本过滤方法
Bokeh提供多种过滤器:
- IndexFilter:按索引过滤
- BooleanFilter:按布尔值过滤
- GroupFilter:按分类值过滤
from bokeh.models import CDSView, IndexFilter
view = CDSView(filter=IndexFilter([0, 2, 4]))
p.scatter(x='x', y='y', source=source, view=view)
自定义JS过滤器
from bokeh.models import CustomJSFilter
js_filter = CustomJSFilter(code='''
const indices = [];
for (let i = 0; i < source.get_length(); i++){
if (source.data['value'][i] > threshold){
indices.push(true);
} else {
indices.push(false);
}
}
return indices;
''')
最佳实践建议
- 对于大型数据集,优先使用ColumnDataSource
- 实时数据更新考虑使用stream()方法
- 分类数据使用factor_mark和factor_cmap
- 复杂计算尽量在客户端通过CustomJS完成
- 共享数据源可实现图表联动效果
通过掌握这些数据技术,您可以构建出高效、交互性强的Bokeh数据可视化应用。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考