How to save selected points in a pandas data frame?

Hi,

I have a Bokeh scatter plot. I want to enable the lasso tool and then save the selected points in a pandas data frame for further processing with python in a Jupyter notebook.

Currently, accessing the selected property of ColumnDataSource returns an empty structure:

{‘0d’: {‘flag’: False, ‘indices’: },

‘1d’: {‘indices’: },

‘2d’: {‘indices’: }}

Thanks,

Logan L

In the notebook, there is push_notebook to push data from python TO Bokeh, but there is not a great mechanism to go the opposite direction. But it is possible in a roundabout way. Jupyter provides a JS function kernel.execute that let's you pass python to execute in the current kernel. So, you could use that in a CusotmJS callback on selections to set some python variable or call some python function. You can study a concrete example in the Datashader InteractiveImage class:

  https://github.com/bokeh/datashader/blob/master/datashader/bokeh_ext.py#L58-L115

Thanks,

Bryan

···

On Oct 19, 2016, at 2:07 PM, [email protected] wrote:

Hi,

I have a Bokeh scatter plot. I want to enable the lasso tool and then save the selected points in a pandas data frame for further processing with python in a Jupyter notebook.

Currently, accessing the `selected` property of `ColumnDataSource` returns an empty structure:

    {'0d': {'flag': False, 'indices': },
     '1d': {'indices': },
     '2d': {'indices': }}

Thanks,
Logan L

--
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/b5d52334-490c-4bc4-9e24-457a73425bcf%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Hi,

Is there any possibility about saving the selection as a filtered pandas data frame without doing it via kernel.execute in jupyter?

My code is:
from random import random

import numpy as np

import pandas as pd

from bokeh.layouts import row, column

from bokeh.models import CustomJS, ColumnDataSource, Button

from bokeh.plotting import figure, output_file, show, curdoc

output_file(“callback.html”)

x = [random() for x in range(500)]

y = [random() for y in range(500)]

df = pd.DataFrame(dict(x=x,y=y))

s1 = ColumnDataSource(df)

p1 = figure(plot_width=400, plot_height=400, tools=“lasso_select”, title=“Select Here”)

p1.circle(‘x’, ‘y’, source=s1, alpha=0.6)

s2 = ColumnDataSource(data=dict(x=, y=))

p2 = figure(plot_width=400, plot_height=400, x_range=(0, 1), y_range=(0, 1),

tools="", title=“Watch Here”)

p2.circle(‘x’, ‘y’, source=s2, alpha=0.6)

savebutton = Button(label=“Save”, button_type=“success”)

savebutton = Button(label=“Save”, button_type=“success”)

savebutton.callback = CustomJS(args=dict(s1=s1), code="""

var inds = s1.selected[‘1d’].indices;

var data = s1.data;

var out = “FSC-A;SSC-A” + “\t”;

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

out += data[‘x’][inds[i]] + “;” + data[‘y’][inds[i]] + “\t”;

}

var res = out.slice(0, -1);

var file = new Blob([res], {type: ‘text/plain’});

var elem = window.document.createElement(‘a’);

elem.href = window.URL.createObjectURL(file);

elem.download = ‘selected-data.txt’;

document.body.appendChild(elem);

elem.click();

document.body.removeChild(elem);

“”")

s1.callback = CustomJS(args=dict(s2=s2), code="""

var inds = cb_obj.selected[‘1d’].indices;

var d1 = cb_obj.data;

var d2 = s2.data;

d2[‘x’] =

d2[‘y’] =

var out = “”;

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

d2[‘x’].push(d1[‘x’][inds[i]])

d2[‘y’].push(d1[‘y’][inds[i]])

}

console.log(s2.data)

console.log(inds)

s2.change.emit();

“”")

layout = row(p1, savebutton,p2)

curdoc().add_root(layout)

curdoc().title = “Selection”

show(layout)

``

My idea is to have something that will export me a pandas data frame instead of saving a plain txt file with savebutton.callback.

Thank you in advance,

Marko

···

On Friday, October 21, 2016 at 5:32:14 PM UTC+2, Bryan Van de ven wrote:

In the notebook, there is push_notebook to push data from python TO Bokeh, but there is not a great mechanism to go the opposite direction. But it is possible in a roundabout way. Jupyter provides a JS function kernel.execute that let’s you pass python to execute in the current kernel. So, you could use that in a CusotmJS callback on selections to set some python variable or call some python function. You can study a concrete example in the Datashader InteractiveImage class:

    [https://github.com/bokeh/datashader/blob/master/datashader/bokeh_ext.py#L58-L115](https://github.com/bokeh/datashader/blob/master/datashader/bokeh_ext.py#L58-L115)

Thanks,

Bryan

On Oct 19, 2016, at 2:07 PM, [email protected] wrote:

Hi,

I have a Bokeh scatter plot. I want to enable the lasso tool and then save the selected points in a pandas data frame for further processing with python in a Jupyter notebook.

Currently, accessing the selected property of ColumnDataSource returns an empty structure:

{'0d': {'flag': False, 'indices': []},
 '1d': {'indices': []},
 '2d': {'indices': []}}

Thanks,

Logan L


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/b5d52334-490c-4bc4-9e24-457a73425bcf%40continuum.io.

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

+1 for this idea - we’ve got a reliable way to save a text file, but it’s unclear how to get data from a javascript object into a separate python object… working in a jupyter notebook or on a bokeh server. Linked plots work great (see this post on linked plots/saving data) – but the selected object is not persistent… In that linked example, all of the data in the first chart (s1) is persistent

as an example after running the code at the link in a jupyter notebook, and then manually selecting data from the first chart

s1.data shows all the datapoints,

{‘x’: [0.3909169814195108,
0.7852990443136825,…
‘y’: [0.8320226897995028,
0.5446850662371783,

but s2 - which dynamically links to selected data in s1 returns and empty set

{‘x’: , ‘y’: }

@surfaceowl I’d recommend starting a new issue as there is a lot of old information in this topic, and things have changed alot in terms of some specific syntax. In any case, it’s definitely possible to save off selection indices in a Bokeh server application (and always has been), at which point you can put them in a DataFrame or whatever you want. In the notebook, the push_notebook function is only for one-way updates, i.e from Python to JS. So if you want to save off selection indices the best bet is to embed a Bokeh server application, or else folks sometimes do things with kernel.execute to store the value back in the Python process (that is way too hacky/fragile for us to do anything with in general, but can be useful for specific situations, YMMV)

1 Like