Select 行来自散景交互式线图中的 ColumnDataSource

Select rows from ColumnDataSource in Bokeh interactive line plot

我一直在尝试 select 行来绘制简单的散景线图。 期望的结果是一个简单的线图,x 轴为 Date,y 轴为 Value。 使用 2 select 小部件我想 select CountryType.

非常欢迎任何建议!

到目前为止我的代码:

import pandas as pd
import numpy as np
from bokeh.models.widgets import Select
from bokeh.models import ColumnDataSource, Select, CDSView, GroupFilter
from bokeh.io import show, output_notebook
from bokeh.plotting import figure

output_notebook()

# base
df = pd.DataFrame({'Country': ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B'],
                   'Date': ['01-01-2020', '01-02-2020', '01-03-2020', '01-01-2020', '01-02-2020', '01-03-2020', '01-01-2020', '01-02-2020', '01-03-2020', '01-01-2020', '01-02-2020', '01-03-2020'],
                   'Type': ['X', 'X', 'X', 'Y', 'Y', 'Y', 'X', 'X', 'X', 'Y', 'Y', 'Y'],
                   'Value': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]})
df['Date'] = pd.to_datetime(df['Date'])

source = ColumnDataSource(df)

country_filter = CDSView(source=source, filters=[GroupFilter(column_name='Country', group='A')])
type_filter = CDSView(source=source, filters=[GroupFilter(column_name='Type', group='X')])

country_select = Select(title="Country:", value="A", options=np.unique(source.data['Country']).tolist())
country_select.js_link('value', country_filter, 'group')

type_select = Select(title="Type:", value="X", options=np.unique(source.data['Type']).tolist())
type_select.js_link('value', type_filter, 'group')

p = figure()
p.line(x='Date', y='Value', source=source, view=view)

layout = row(p, column(country_select, type_select))

show(layout)

你差不多明白了。这是一个工作版本。需要注意两点:

  1. 我必须手动 link 将过滤器对视图 change 信号的更改分组 - 现在 Bokeh 不会在内部 link
  2. 由于您使用的是线,因此此代码将产生一条警告,提示您使用具有连接拓扑的字形过滤器。在你的情况下可以安全地忽略它
import numpy as np
import pandas as pd
from bokeh.io import show
from bokeh.layouts import row, column
from bokeh.models import ColumnDataSource, Select, CDSView, GroupFilter, CustomJS
from bokeh.plotting import figure

df = pd.DataFrame({'Country': ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B'],
                   'Date': ['01-01-2020', '01-02-2020', '01-03-2020', '01-01-2020', '01-02-2020', '01-03-2020',
                            '01-01-2020', '01-02-2020', '01-03-2020', '01-01-2020', '01-02-2020', '01-03-2020'],
                   'Type': ['X', 'X', 'X', 'Y', 'Y', 'Y', 'X', 'X', 'X', 'Y', 'Y', 'Y'],
                   'Value': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]})
df['Date'] = pd.to_datetime(df['Date'])

source = ColumnDataSource(df)

country_filter = GroupFilter(column_name='Country', group='A')
type_filter = GroupFilter(column_name='Type', group='X')
view = CDSView(source=source, filters=[country_filter, type_filter])

# Alas, we need this manual step to make the view know about the filters' changes.
for f in view.filters:
    f.js_on_change('group', CustomJS(args=dict(view=view),
                                     code="view.properties.filters.change.emit();"))

country_select = Select(title="Country:", value="A", options=np.unique(source.data['Country']).tolist())
country_select.js_link('value', country_filter, 'group')

type_select = Select(title="Type:", value="X", options=np.unique(source.data['Type']).tolist())
type_select.js_link('value', type_filter, 'group')

p = figure()
p.line(x='Date', y='Value', source=source, view=view)

show(row(p, column(country_select, type_select)))