1

This question has been posted and answered on Bokeh Discourse.


I wrote an interactive data visualization script with bokeh taking use of JavaScript callbacks (MWE below). The data filtering is noticeably slow starting at around 10k data points, and above 100k becomes impossible to work with. This is also observed when running the code within a Jupyter Notebook. This effect is mostly noticed in regions with more data points.

  • Is this expected? If not, how can I speed up the visualization?
  • General comments on the code, specifically related to correct/incorrect usage of bokeh's functionalities, are welcome.

Thank you.

import numpy as np
from bokeh.io import output_file, show
from bokeh.models import CDSView, ColumnDataSource as CDS, CustomJSFilter
from bokeh.models import CustomJS, RangeSlider, Range1d
from bokeh.plotting import Figure
from bokeh.layouts import layout 
output_file('test.hml') # alternatively one could use output_notebook()

#generate the data
npoints = 50000
data = dict(exp=np.random.exponential(1, size=npoints),
            gau=np.random.normal(0, 0.5, size=npoints),
            )

source = CDS(data=data)

slider  = RangeSlider(start=0, end=10, value=(0, 10), step=.1, title="Exp")

callback = CustomJS(args=dict(s=source), code="""
    s.change.emit();
""")
slider.js_on_change('value', callback)

filt = CustomJSFilter(args=dict(slider=slider), code="""
        var indices = [];
        var start = slider.value[0];
        var end = slider.value[1];

        for (var i=0; i < source.get_length(); i++){
            if (source.data['exp'][i] >= start && source.data['exp'][i] <= end){
                indices.push(true);
            } else {
                indices.push(false);
            }
        }
        return indices;
        """)

view = CDSView(source=source, filters=[filt])

fig = Figure(plot_width=450, plot_height=350)
fig.circle(x='exp', y='gau', source=source, view=view)

#fix ranges (otherwise they change during filtering)
fig.x_range=Range1d(-1, 11)
fig.y_range=Range1d(-3.5, 3.5)

lay = layout([[slider], [fig]])
show(lay)
unvarnished
  • 95
  • 1
  • 8

0 Answers0