Limiting the amount of rendered glyphs in a graph

Is it possible to limit glyph rendering in bokeh? The figure becomes really unresponsive after few thousand glyphs and I need to plot 100k-1M datapoints. There is no need to show all of them at once, like if one glyph overlaps with another at all, only one would be shown. And then when zoomed in the glyph(a circle in this case) that was really close to another would be shown. Also the tooltip is needed. I have two examples below, could someone also say why the example 2 takes much longer to render? as in the more glyphs there is in a figure the more time it takes to add one more.

I start this with

>bokeh serve .\example.py
example.py
#EXAMPLE1START---------------------------------------------------------
from bokeh.models.sources import ColumnDataSource
from bokeh.plotting import figure, curdoc
from bokeh.layouts import column

data = {'x_values':[],
        'y_values':[]}
source = ColumnDataSource(data=data)
TOOLTIPS = [("index", "$index")]
p = figure(title="plot_test",tooltips=TOOLTIPS)
side = 10
for horizontal in range(side):
    for vertical in range(side):
        new_data = {'x_values':[horizontal],
                    'y_values':[vertical]}
        source.stream(new_data)
p.circle(x='x_values',y='y_values',source=source,)

doc = curdoc()
doc.add_root(column(p))
#EXAMPLE1END---------------------------------------------------------
#EXAMPLE2START---------------------------------------------------------
# from bokeh.models.sources import ColumnDataSource
# from bokeh.plotting import figure, curdoc
# from bokeh.layouts import column

# TOOLTIPS = [("tooltip", "$x")]
# p = figure(title="plot_test",tooltips=TOOLTIPS)
# side = 100
# for horizontal in range(side):
#     for vertical in range(side):
#         p.circle(x=horizontal,y=vertical)

# doc = curdoc()
# doc.add_root(column(p))
#EXAMPLE2END---------------------------------------------------------

Hi @lassila

For “big data” applications, packages like datashader exist, but to my knowledge those are not compatible with your requirement of having tooltips for the individual points. This is because they essentially process the data and pass images to the rendering engine.

Controlling what specific points to render is typically relegated to the user software. I think what you are trying to accomplish is doable but would require you to write the specific interactions and callbacks with judicious use of bokeh source-data patching, streaming, or whatever makes the most sense on how your data are provided and/or updated dynamically.

The main takeaway from your two illustrative examples is that you should use vectorization wherever possible. In short, creating 10,000 renderers each with scalar data and its associated individual circle is less efficient than a single glyph renderer that encompasses 10,000 points and their circles.

HV + Datashader has some kind of hover capability on datashader output, but I am not very familiar with its capabilities and/or compromises. Perhaps @Philipp_Rudiger can comment more.

If the the bottleneck is truly drawing , then it’s possible you could use CDS views here to limit what is drawn. But as with anything profiling/performance related, it is generally impossible to say anything concrete without getting into details and running real code.

In short, creating 10,000 renderers each with scalar data and its associated individual circle is less efficient than a single glyph renderer that encompasses 10,000 points and their circles.

I just want to re-iterate what @_jm has said, because it can’t be stressed enough. There are lots of ways the library might have been parceled up for different API, performance, and usage scenarios. Bokeh chose to focus on configuring and updating data sources as the primary mode of operatrion. Glyph renderers are fairly heavyweight but are designed to be able to “vectorize” over data sources, so that is the natural usage pattern that should be followed. You can draw 200k circles with one webgl circle renderer and one data source, but making 200k individual circle renderers will absolutely blow up any browser.