I am stuck trying to select rows to plot in a simple Bokeh line plot.
The desired result is a simple line plot with Date
on the x-axis and Value
on the y-axis.
Using 2 select widgets I would like to select Country
and Type
.
Any suggestions a more than welcome!
My code so far:
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)
You almost got it. Here's a working version. Two things to note:
change
signal - right now Bokeh doesn't make that link internallyimport 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)))