☰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

Jittered-categorical doesn't move when corresponding range is reordered

Community Support
sggaffney
sggaffney

I have a scatter plot involving a categorical axis in which I’d like to have some jitter to the categorical values. The jitter function accomplishes this, providing the corresponding factor range as range argument. But when I reorder the range (and axis), the jittered points don’t move along with it as I expected—they stay put. If this is the intended behavior, is there a straightforward way I can get the jittered values to move when the range changes? Below is a brief example where a button reverses a categorical axis: red jittered points move, blue jittered ones don’t. (Tested in 2.2.0, 2.2.3, 2.3.0dev8)

from bokeh.transform import jitter
from bokeh.models import ColumnDataSource, FactorRange, CustomJS
from bokeh.models.widgets import Button
from bokeh.layouts import column
from bokeh.plotting import figure
from bokeh.io import show

source = ColumnDataSource({
    'name': ['a', 'a', 'a', 'a', 'a'],
    'val': [1, 1, 1, 1, 1],
})

p = figure(x_range=FactorRange(factors=['a', 'b']),  
           y_range=(0, 2), plot_width=200, plot_height=200)

p.scatter(x=jitter('name', 0.5, range=p.x_range), y='val', size=5, alpha=0.5, color='blue', source=source)
p.scatter(x='name', y=jitter('val', 0.5), size=5, color='red', alpha=0.5, source=source)

button = Button(label='Reorder factors')
button.js_on_click(CustomJS(args={'x_range': p.x_range}, code="""
    const factors = [...x_range.factors];
    const reversed = factors.reverse();
    x_range.factors = reversed;
"""))
column = column(button, p)
show(column)
⌁   Link to post
Bryan
Bryan

@sggaffney Looking at the BokehJS code I am afraid this is simply a deficiency in the current caching behavior of the jitter transform. [1] It is caching the final computed values but it should really just cache the offsets. This will have to be addressed in Bokeh itself, and I don’t have any immediate workaround to suggest. Please file a bug report issue with all of your information.


  1. and just FYI it is caching at all because if it recomputes all the time, then e.g it recomputes every mouse move of a pan operation, and that is definitely not desirable. ↩︎

⌁   Link to post

End of archived discussion · Replies are disabled