Hi,
The setup I have is initially empty plots (with initialized CDS source) with the x_range
defined as FactorRange
(empty list).
From a Select
widget the user can choose a case (Case 1 and an empty case). The objective is that if the empty case is chosen then the data in the CDS is set to empty data and the x_range
factors should be set to empty list.
However if I do this I get an error in the browser console (Firefox: TypeError: t is undefined
, Safari: TypeError: undefined is not an object (evaluating 't.length’)
. In the example below I have 2 plots, in the one to the right I do not reset x_range
factors, but with an empty data in the CDS the factors seems to be grouped together in the top left corner of the figure which is not so nice visually.
So, what is the proper way to reset, or hide the factors if no data present in the CDS?
Running this as bokeh serve
on Mac OS, Bokeh 1.3.4.
from bokeh.io import curdoc
from bokeh.models import ColumnDataSource, FactorRange
from bokeh.models.widgets import Select
from bokeh.plotting import figure
from bokeh.layouts import column, widgetbox, row
import pandas as pd
fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
data = {'fruits' : fruits,
'2015' : [2, 1, 4, 3, 2, 4],
'2016' : [5, 3, 3, 2, 4, 6],
'2017' : [3, 2, 4, 4, 5, 3]}
df = pd.DataFrame.from_dict(data)
df=df.set_index('fruits').stack().reset_index()
df=df.rename(columns={'level_1':'year', 0:'value'})
df=df.set_index(['fruits','year'])
cats = df.index.values
empty_src = {
'categories': [],
'values': [],
}
def case_update(attr, old, new):
if new == '':
source.data = empty_src
p1.x_range.factors = list([])
else:
source.data = {
'categories': cats,
'values': df['value']
}
p1.x_range.factors = list(cats)
p2.x_range.factors = list(cats)
source = ColumnDataSource(
data = empty_src
)
def setup_plot(title):
p = figure(
x_range=FactorRange(''),
plot_height=300,
title=title,
)
p.vbar(
x='categories',
top='values',
width=0.9,
source=source
)
p.y_range.start = 0
p.x_range.range_padding = 0.1
p.xaxis.major_label_orientation = 1
p.xgrid.grid_line_color = None
return p
p1 = setup_plot('factors = list([])')
p2 = setup_plot('No reset of factors')
case = Select(
title = 'Case',
value = '',
options = ['', 'Case 1']
)
case.on_change('value', case_update)
layout = column(
widgetbox(case),
row(p1, p2)
)
curdoc().add_root(layout)
curdoc().title = "Select"