Bokeh - 过滤数据

通常,您可能希望获取与满足特定条件的部分数据相关的图,而不是整个数据集。 bokeh.models 模块中定义的 CDSView 类的对象通过在其上应用一个或多个过滤器返回正在考虑的 ColumnDatasource 的子集。

IndexFilter 是最简单的过滤器类型。 您必须仅指定数据集中要在绘制图形时使用的那些行的索引。

以下示例演示了使用 IndexFilter 来设置 CDSView。 结果图显示了 ColumnDataSource 的 x 和 y 数据系列之间的线条字形。 视图对象是通过对其应用索引过滤器来获得的。 作为 IndexFilter 的结果,该视图用于绘制圆形字形。


示例

from bokeh.models import ColumnDataSource, CDSView, IndexFilter
from bokeh.plotting import figure, output_file, show
source = ColumnDataSource(data = dict(x = list(range(1,11)), y = list(range(2,22,2))))
view = CDSView(source=source, filters = [IndexFilter([0, 2, 4,6])])
fig = figure(title = 'Line Plot example', x_axis_label = 'x', y_axis_label = 'y')
fig.circle(x = "x", y = "y", size = 10, source = source, view = view, legend = 'filtered')
fig.line(source.data['x'],source.data['y'], legend = 'unfiltered')
show(fig)

输出

索引过滤器

要从数据源中选择那些满足特定布尔条件的行,请应用 BooleanFilter。

典型的 Bokeh 安装包括 sampledata 目录中的许多样本数据集。 对于下面的示例,我们使用以 unemployment1948.csv 形式提供的 unemployment1948 数据集。 它存储了自 1948 年以来美国每年的失业率。我们只想为 1980 年以后生成一个图。 为此,通过在给定数据源上应用 BooleanFilter 来获得 CDSView 对象。

from bokeh.models import ColumnDataSource, CDSView, BooleanFilter
from bokeh.plotting import figure, show
from bokeh.sampledata.unemployment1948 import data
source = ColumnDataSource(data)
booleans = [True if int(year) >= 1980 else False for year in
source.data['Year']]
print (booleans)
view1 = CDSView(source = source, filters=[BooleanFilter(booleans)])
p = figure(title = "Unemployment data", x_range = (1980,2020), x_axis_label = 'Year', y_axis_label='Percentage')
p.line(x = 'Year', y = 'Annual', source = source, view = view1, color = 'red', line_width = 2)
show(p)

输出

BooleanFilter

为了更加灵活地应用过滤器,Bokeh 提供了一个 CustomJSFilter 类,借助该类可以使用用户定义的 JavaScript 函数过滤数据源。

下面给出的例子使用了相同的数据。 定义一个 CustomJSFilter 来绘制 1980 年及之后的数据。

from bokeh.models import ColumnDataSource, CDSView, CustomJSFilter
from bokeh.plotting import figure, show
from bokeh.sampledata.unemployment1948 import data
source = ColumnDataSource(data)
custom_filter = CustomJSFilter(code = '''
   var indices = [];

   for (var i = 0; i < source.get_length(); i++){
      if (parseInt(source.data['Year'][i]) > = 1980){
         indices.push(true);
      } else {
         indices.push(false);
      }
   }
   return indices;
''')
view1 = CDSView(source = source, filters = [custom_filter])
p = figure(title = "Unemployment data", x_range = (1980,2020), x_axis_label = 'Year', y_axis_label = 'Percentage')
p.line(x = 'Year', y = 'Annual', source = source, view = view1, color = 'red', line_width = 2)
show(p)