import numpy as np

from bokeh.io import vplot, hplot
from bokeh.plotting import figure, show, output_file
from bokeh.models.sources import ColumnDataSource
from bokeh.models import Slider, CustomJS, Dropdown, Toggle, Paragraph
from bokeh.models.transforms import Jitter

N = 50
source = ColumnDataSource(data=dict(x=[1]*N + [2]*N, xp=[1]*N + [2]*N, xplot=[1]*N + [2]*N, col=['#ab324b']*N + ['#0022aa']*N, y=np.random.random(2*N)*10))

jitter = Jitter(mean=0, width=0)

p = figure(x_range=(0, 3), y_range=(0,10))
scatter_obj = p.scatter(x='xplot', y='y', color='col', source=source, size = 10, alpha=0.5)

enable_callback=CustomJS(args=dict(scatter_obj=scatter_obj, source=source, figure=p, jitter=jitter), code="""
    if(button.get('active') == true) {
        var data=source.get('data')
        for (i=0; i < data['y'].length; i++) {
            data['xplot'][i] = data['xp'][i]
        }
    } else {
        var data=source.get('data')
        for (i=0; i < data['y'].length; i++) {
            data['xplot'][i] = data['x'][i]
        }
    }
    source.trigger('change')
    figure.trigger('change')
""")

width_callback=CustomJS(args=dict(jitter=jitter, source=source, figure=p), code="""
    jitter.set('width', slider.get('value'))
    data=source.get('data')
    for (i=0; i < data['y'].length; i++) {
        data['xp'][i] = jitter.compute(data['x'][i])
    }
    if(button.get('active') == true) {
        var data=source.get('data')
        for (i=0; i < data['y'].length; i++) {
            data['xplot'][i] = data['xp'][i]
        }
    }
    source.trigger('change')
    figure.trigger('change')
""")

center_callback=CustomJS(args=dict(jitter=jitter, source=source, figure=p), code="""
    jitter.set('mean', slider.get('value'))
    data=source.get('data')
    for (i=0; i < data['y'].length; i++) {
        data['xp'][i] = jitter.compute(data['x'][i])
    }
    if(button.get('active') == true) {
        var data=source.get('data')
        for (i=0; i < data['y'].length; i++) {
            data['xplot'][i] = data['xp'][i]
        }
    }
    source.trigger('change')
    figure.trigger('change')
""")

distribution_callback=CustomJS(args=dict(jitter=jitter, source=source, figure=p), code="""
    jitter.set('distribution', menu.get('value'))
    data=source.get('data')
    for (i=0; i < data['y'].length; i++) {
        data['xp'][i] = jitter.compute(data['x'][i])
    }
    if(button.get('active') == true) {
        var data=source.get('data')
        for (i=0; i < data['y'].length; i++) {
            data['xplot'][i] = data['xp'][i]
        }
    }
    source.trigger('change')
    figure.trigger('change')
""")

enable_button = Toggle(label='Enable Jitter', type='success', callback=enable_callback)
enable_callback.args['button'] = enable_button

width_slider = Slider(start=0, end=2, value=0, step=0.01, title='Width', callback=width_callback, callback_policy='continuous')
width_callback.args['slider'] = width_slider
width_callback.args['button'] = enable_button

center_slider = Slider(start=-1, end=1, value=0, step=0.01, title='Center', callback=center_callback, callback_policy='continuous')
center_callback.args['slider'] = center_slider
center_callback.args['button'] = enable_button

distribution_dropdown = Dropdown(label='Distribution', type='success', menu=[('Uniform', 'uniform'), ('Normal', 'normal')], callback=distribution_callback)
distribution_callback.args['menu'] = distribution_dropdown
distribution_callback.args['button'] = enable_button

title = Paragraph(text='Jitter Parameters')
spacer = Paragraph(text=' ')

output_file("transform_jitter.html", title="Example Transforms")

show(hplot(p, vplot(enable_button, spacer, title, spacer, center_slider, width_slider, distribution_dropdown)))

@@ -220,16 +220,24 @@
 aragraph
+, Select
 %0Afrom bo
@@ -1083,37 +1083,8 @@
 e')%0A
-    figure.trigger('change')%0A
 %22%22%22)
@@ -1560,37 +1560,8 @@
 e')%0A
-    figure.trigger('change')%0A
 %22%22%22)
@@ -2037,37 +2037,8 @@
 e')%0A
-    figure.trigger('change')%0A
 %22%22%22)
@@ -2170,32 +2170,46 @@
 enu.get('value')
+.toLowerCase()
 )%0A    data=sourc
@@ -2540,37 +2540,8 @@
 e')%0A
-    figure.trigger('change')%0A
 %22%22%22)
@@ -2594,23 +2594,23 @@
 , type='
-success
+default
 ', callb
@@ -3142,33 +3142,29 @@
 ion_
-dropdown = Dropdown(label
+select = Select(title
 ='Di
@@ -3172,71 +3172,61 @@
 trib
-u
+i
 tion', 
-type='success', menu=%5B('Uniform', 'u
+value='Uniform', options=%5B'U
 niform'
-)
 , 
-(
 'Normal'
 , 'n
@@ -3225,19 +3225,8 @@
 mal'
-, 'normal')
 %5D, c
@@ -3306,24 +3306,22 @@
 ibution_
-dropdown
+select
 %0Adistrib
@@ -3611,16 +3611,14 @@
 ion_
-dropdown
+select
 )))%0A

Remove unneeded figure triggers and change the dropdown to a select.