☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

How do I reset factor range to empty list without js error?

Community Support
Jonas_Grave_Kristens
Jonas_Grave_Kristens

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_rangefactors, 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 serveon 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"
⌁   Link to post

End of archived discussion · Replies are disabled