Slider Interactions

Hello,

I want to configure a slider with date values, so that when the user drags the slider, the scatter plot graph makes all points that have an associated discovery date less than or equal to the slider value visible, and all later points are hidden. What would be the best way to do this?

Hi mblucas,

There are a few possible approaches. If you'd like a static document that does not require a Bokeh server to interact with and use, then you can make use of our recently added JS Callbacks. But this will require writing a little JavaScript. The simplest thing would be to configure the callback with the data source for the plot (which needs to have columns for the position, visuals, but also the column for the discovery date), then in the callback loop through the data making comparisons to set a selection. I have attached a minimal example at the bottom that could hopefully get you started.

The other option is to use a server, then you could make the comparisons, set the selection, etc. in python, but that would require hosting the plot on your own permanently deployed server, or having users run their own server. But if you are interested in pursuing this route, let us know for more information.

import numpy as np

from bokeh.io import output_file, show, vform
from bokeh.plotting import figure
from bokeh.models import Callback, Circle, ColumnDataSource, Slider

N = 200

x = np.linspace(0, 5, N)
y = np.sin(x) + np.random.random(N)*0.1
index = np.arange(N)

output_file("slider_select.html")

source = ColumnDataSource(data=dict(x=x, y=y, index=index))

p = figure(plot_width=400, plot_height=400)
p.circle("x", "y", size=5, color="navy", alpha=0.6, source=source, name="mycircle")

invisible_glyph = Circle(fill_alpha=0.0, line_alpha=0.0)

renderer = p.select(name="mycircle")
renderer.selection_glyph = renderer[0].glyph.clone()
renderer.nonselection_glyph = invisible_glyph

callback = Callback(args=dict(source=source), code="""
    var value = cb_obj.get('value')

    var data = source.get('data');
    index = data['index']
    new_indices =
    for (i = 0; i < index.length; i++) {
        if (i <= value) {
            new_indices.push(i)
        }
    }
    selected = source.get('selected')
    selected['1d'].indices = new_indices
    source.trigger('change');
""")

slider = Slider(start=0, end=N, value=N, step=1, title="index", callback=callback)

show(vform(slider, p))

···

On Aug 6, 2015, at 11:28 AM, [email protected] wrote:

Hello,

I want to configure a slider with date values, so that when the user drags the slider, the scatter plot graph makes all points that have an associated discovery date less than or equal to the slider value visible, and all later points are hidden. What would be the best way to do this?

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/bdcd6914-1ea1-4514-aefb-baa99b6f3bb0%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Thank you for the quick and helpful reply! This is exactly what I’m looking for.

I don’t quite understand what these two lines are doing:

selected = source.get(‘selected’)

selected[‘1d’].indices = new_indices

Where does ‘selected’ come from in source, and what does ‘1d’ mean?

···

On Thursday, August 6, 2015 at 10:10:34 AM UTC-7, Bryan Van de ven wrote:

Hi mblucas,

There are a few possible approaches. If you’d like a static document that does not require a Bokeh server to interact with and use, then you can make use of our recently added JS Callbacks. But this will require writing a little JavaScript. The simplest thing would be to configure the callback with the data source for the plot (which needs to have columns for the position, visuals, but also the column for the discovery date), then in the callback loop through the data making comparisons to set a selection. I have attached a minimal example at the bottom that could hopefully get you started.

The other option is to use a server, then you could make the comparisons, set the selection, etc. in python, but that would require hosting the plot on your own permanently deployed server, or having users run their own server. But if you are interested in pursuing this route, let us know for more information.

import numpy as np

from bokeh.io import output_file, show, vform

from bokeh.plotting import figure

from bokeh.models import Callback, Circle, ColumnDataSource, Slider

N = 200

x = np.linspace(0, 5, N)

y = np.sin(x) + np.random.random(N)*0.1

index = np.arange(N)

output_file(“slider_select.html”)

source = ColumnDataSource(data=dict(x=x, y=y, index=index))

p = figure(plot_width=400, plot_height=400)

p.circle(“x”, “y”, size=5, color=“navy”, alpha=0.6, source=source, name=“mycircle”)

invisible_glyph = Circle(fill_alpha=0.0, line_alpha=0.0)

renderer = p.select(name=“mycircle”)

renderer.selection_glyph = renderer[0].glyph.clone()

renderer.nonselection_glyph = invisible_glyph

callback = Callback(args=dict(source=source), code="""

var value = cb_obj.get('value')



var data = source.get('data');

index = data['index']

new_indices = []

for (i = 0; i < index.length; i++) {

    if (i <= value) {

        new_indices.push(i)

    }

}

selected = source.get('selected')

selected['1d'].indices = new_indices

source.trigger('change');

“”")

slider = Slider(start=0, end=N, value=N, step=1, title=“index”, callback=callback)

show(vform(slider, p))

On Aug 6, 2015, at 11:28 AM, mbl…@princeton.edu wrote:

Hello,

I want to configure a slider with date values, so that when the user drags the slider, the scatter plot graph makes all points that have an associated discovery date less than or equal to the slider value visible, and all later points are hidden. What would be the best way to do this?


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/bdcd6914-1ea1-4514-aefb-baa99b6f3bb0%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

"selected" is an attribute on column data sources. It is a JS object (a dictionary) that holds indices for different kinds of selections. For now most everything is going to be a "1d" selection, which refers to the fact that the indices of the selected points are indices into a 1d array. You can imagine later allowing selections over 2d images, and then you'd have to record 2d (i,j) tuples as selection indices that describe which rows and columns of the 2d image data are selected. Or for the MultiLine glyph, you could record which point (j) on which line (i) was selected as an (i, j) selection. These are for the future, however.

Bryan

···

On Aug 6, 2015, at 3:01 PM, [email protected] wrote:

Thank you for the quick and helpful reply! This is exactly what I'm looking for.

I don't quite understand what these two lines are doing:

selected = source.get('selected')
selected['1d'].indices = new_indices

Where does 'selected' come from in source, and what does '1d' mean?

Hello,
I came across this posting while learning to work with Bokeh recently and it was very helpful. For other reasons I need to switch to doing something similar with Bokeh server. I have been researching but there are not a lot of great examples online that were as easy for me to interpret as yours. Is it possible for you to reproduce an example for how you would format the same concept you show above via a Bokeh server? I eventually want to create it for a MultiLine glyph but can also find no examples of this.

Thank-you so much for your help,

Hannah

···

On Thursday, August 6, 2015 at 4:21:10 PM UTC-4, Bryan Van de ven wrote:

On Aug 6, 2015, at 3:01 PM, mbl…@princeton.edu wrote:

Thank you for the quick and helpful reply! This is exactly what I’m looking for.

I don’t quite understand what these two lines are doing:

selected = source.get(‘selected’)
selected[‘1d’].indices = new_indices

Where does ‘selected’ come from in source, and what does ‘1d’ mean?

“selected” is an attribute on column data sources. It is a JS object (a dictionary) that holds indices for different kinds of selections. For now most everything is going to be a “1d” selection, which refers to the fact that the indices of the selected points are indices into a 1d array. You can imagine later allowing selections over 2d images, and then you’d have to record 2d (i,j) tuples as selection indices that describe which rows and columns of the 2d image data are selected. Or for the MultiLine glyph, you could record which point (j) on which line (i) was selected as an (i, j) selection. These are for the future, however.

Bryan