☰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

Efficient plotting of function defined analytically (via CustomJSExpr)

Community Support
annulen
annulen

Hello,

I need to plot a number of functions defined analytically (via
CustomJSExpr). As far as I understand, Bokeh requires using explicitly
set x array for plot. But amount of (x,y) points that are actually
needed to draw plot lines depend heavily on the range selected by user:
as range becomes smaller, x points should be placed more densely to
keep plots accurate. And using small steps for x over the whole range is
undesirable because functions are quite costly to re-evaluate after
their parameters are interactively changed.

I’ve looked at topic

but I haven’t identified an example which is close enough to my case.
What I’d like to have is not actually a downsampling of dataset, but
dynamic generation of “dataset” (i.e., x values).

Any ideas?

cc @Philipp_Rudiger @James_A_Bednar1

⌁   Link to post
Bryan
Bryan

I think using CustumJSExpr will not work well if your goal is non-uniform sampling, since each expression only affects on thing (i.e. x- or y-coordinates) at a time. I think you’d find better success using a CustomJS callback on range updates. The callback can compute first compute the appropriate x-coordinate distribution based on the range, and then compute the y-values for those computed c-coordinate [1]. Then you can set both the new data for both x and y fields at the same time to update the plot.


  1. Or however, maybe a range start and end is just an initial input, and you have to perform some more complicated iterative mesh refinement. The point is that you can compute both a whole new array of x-coordinates, and a new corresponding array of y-values up front, then update the CDS with both at the same time at the end of the callback. ↩︎

⌁   Link to post
annulen
annulen

“Derived datasources” indeed sounds like a great concept which describes very well what I’m doing now. I actually have “small” datasources with pairs (x, amplitude), from which I build compositions of Gaussian functions, centered in those x’es, scaled by respective amplitudes, and sigma value is taken from UI setting. Each of those compositions form a glyph on the plot. And on top of that, I have “summing” glyph which displays a sum of a few other existing Bokeh glyphs selected by user in UI and multiplied by with user-specified coefficients.

However, that topic doesn’t provide an actual outline how to implement proper derived datasource in JS, and corresponding feature request has not been addressed yet too.

⌁   Link to post
gmerritt123
gmerritt123

Basic/naive approach I’ve done as follows:

  1. Make a “base” CDS (or, probably better, a custom DataModel) to hold the process variables from which to create your derived CDS.
  2. Instantiate (you can do this python side or JS-side) an empty CDS to hold your derived data.
  3. Point your renderers etc. to run off the derived CDS.
  4. Build CustomJS (to trigger on user action) that will…
  • Collect all necessary widget states/views, and update the “base” CDS or DataModel
  • Determine the appropriate range/resolution to evaluate the function… e.g. simple 1D case, say user is zoomed to x = 1 to 100 on the figure, therefore we’ll evaluate our function at 1000 points evenly spaced from from x=1 to 100, so populate an array accordingly, e.g. var xs = [1,1.1,1.2....99.9,100]
  • Evaluate the function at those values e.g. var ys = xs.map(y=>some_function(y,....other widget state variables as args)
  • Update the derived CDS with those values e.g. `derived_src.data = {‘xs’:xs,‘ys’:ys}

Obviously this can get more complex, as you can “stack” derived datasources on top of each other etc, but the overall paradigm doesn’t change. When user changes something, check the necessary states, determine the right range/resolution to evaluate things, evaluate them, and update the derived datasources with that.

⌁   Link to post

End of archived discussion · Replies are disabled