How does one manage glyphs on a figure?

Hi,
I read your answer as per below. You explained very well here. You mentioned 3 ways here. However I would like to employ first approach in my project . Can you provide me any example on how to recreate new plot at the same location in layout as that of old plot.

Thanks,
Avinash

···

On Thursday, June 9, 2016 at 7:38:50 PM UTC+5:30, Bryan Van de ven wrote:

Hi,

Bokeh is a library that spans (at least) two languages and runtime environments, which can sometimes be confusing. Looking at your code, I see you are updating data sources in a JS callback. This only affects the JavaScript data source object in the JavaScript runtime, and will have no reflection into the python space normally. If you need the python/JS to stay “in sync” with one another, that is the primary purpose of the Bokeh server. However, work to make the Bokeh server integrate with the notebook is still ongoing.

However, there are other options for keeping the JS and python objects in sync, namely the “push_notebook” function that was demonstrated in the notebooks I linked earlier. This function allows you to make changes to the python objects (for instance, the glyphs and data sources that you have created) and then have those changes update an existing plot in a notebook cell. Right now this update only happens in one direction: from Python → JS, although there are other folks interested in and working on ideas to enable the “reverse” direction updates as well.

Regarding where to find the glyphs, do you mean on the python side? Or on the JS side? On the python side you you are creating the glyphs and adding them with .add_glyph, you can just use the reference to the glyph you created? Or when you create with, e.g. fig.circle(…) that fucntion returns the glyph renderer, just store it in a variable if you need to use it. Technically, glyph renderers are stored in the .renderers property of Plots, but I would not recommend rooting around there by hand. Specifically the “Continuous Updating” notebook I linked earlier has an example of updating both the data and appearance of an existing glyph using python and push_notebook. This sounds like what you were asking for? There is not any easy way to remove glyphs at the moment, other options would be:

  • recreate a new plot

  • set the glyph to be invisble

  • update the glyphs data

Perhaps it would help to back away from specific implementation questions, because it may be the case that there is some other better path or approach. Can you describe what you are trying to accomplish, at a higher level, without referring to any potential implementation details? That is, more like “I want to have this sort of plot, that shows this kind of data, and these three widgets. When a button is pushed, I want such and such to happen”.

Thanks,

Bryan

On Jun 9, 2016, at 7:54 AM, Gabriel Diaz [email protected] wrote:

Thanks Bryan. Unless I missed it, I don’t see an answer to my question in those otherwise very helpful guides.

Let me try and restate my issue, in case it lacked clarity (that large code dump didn’t help!). I am adding new glyphs to my figure through modification of a column datasource within a javascript callback function. I would subsequently like to access, manipulate, and perhaps remove these glyphs through ipywidget callbacks, using Python.

However, I cannot find where information about individual glpyhs objects stored.

The callback I use is a modified version of the reference example on callbacks for box select. My intuition was that this callback is manipulating the column datasource, which was accumulating the information of multiple glyphs. However, even when multiple ‘rects’ have been added to my figure, the columnData source, when accessed through Python, remains empty. Perhaps I need to invoke the Python kernel from within the JS callback function to return the modified source to the Python workspace?

I’ve explored all the related Bokeh objects, and have done due diligence looking for this answer elsewhere, without luck.

Thanks

  • gD

Gabriel J. Diaz, Ph.D.

Assistant Professor

Rochester Institute of Technology

Chester F. Carlson Center for Imaging Science

Founder of PerForM Labs

Click for demos.

Office 2108, Building #76

Rochester, NY 14623

Office: (585) 475-6215

gabrie…@rit.edu

On Wed, Jun 8, 2016 at 7:26 PM, Bryan Van de Ven [email protected] wrote:

I would suggest studying the examples here:

    [https://github.com/bokeh/bokeh/tree/master/examples/howto/notebook_comms](https://github.com/bokeh/bokeh/tree/master/examples/howto/notebook_comms)

Thanks,

Bryan

On Jun 8, 2016, at 4:13 PM, Gabriel Diaz [email protected] wrote:

Apologies. An example is included in the attached *.ipynb

  • gD

On Wednesday, June 8, 2016 at 5:12:17 PM UTC-4, Gabriel Diaz wrote:

Hello! I’m looking for a way a way to access the glyphs once they have been added to the figure. Upon access, I will need to change visual attributes, and, potentially, to remove the glyph from the figure. Note that the glyphs will be added interactively, through a callback function using the box select tool.

Code from my notebook is pasted below!

If you want to know more, read more to find out why…

Thanks!

  • gD

My goal is to create a somewhat robust tool for that students can use to label events in a time-series. The eventual goal is that they will use box-selection to mark a region, and use one of several ipywidget buttons that will…

  • Label the patch as event type A,B, or C (depending upon the button pressed)
  • Record the event type and start/stop time (on X) of the event in a pandas dataframe
  • Update the glyph to color-code the event

I would also like to provide the user the ability to remove a selected glyph from the dataframe and figure.

Example Event Labeller Last Checkpoint: 5 minutes ago (autosaved)

Python 2

  • File
  • Edit
  • View
  • Insert
  • Cell
  • Kernel
  • Help

CodeMarkdownRaw NBConvertHeading

CellToolbar

In [1]:

from future import division

import pandas as pd

import numpy as np

import bokeh.plotting as bkP

import bokeh.models as bkM

from bokeh.palettes import Spectral6

from bokeh.embed import file_html

from bokeh.resources import CDN

bkP.output_notebook()

x

from future import division

import pandas as pd

import numpy as np

import bokeh.plotting as bkP

import bokeh.models as bkM

from bokeh.palettes import Spectral6

from bokeh.embed import file_html

from bokeh.resources import CDN

bkP.output_notebook()

/Users/diaz/anaconda/lib/python2.7/site-packages/pandas/computation/init.py:19: UserWarning: The installed version of numexpr 2.4.4 is not supported in pandas and will be not be used

UserWarning)

BokehJS successfully loaded

In [41]:

x

source = bkM.ColumnDataSource(data=dict(x=, y=, width=, height=,leftEdge=,rightEdge=))

boxCallback = bkM.CustomJS(args=dict(source=source), code=“”"

    // get data source from Callback args
    var data = source.get('data');

    /// get BoxSelectTool dimensions from cb_data parameter of Callback
    var geometry = cb_data['geometry'];

    /// calculate Rect attributes
    var width = geometry['x1'] - geometry['x0'];
    var height = geometry['y1'] - geometry['y0'];
    var x = geometry['x0'] + width/2;
    var y = geometry['y0'] + height/2;
    var leftEdge = geometry['x0']
    var rightEdge = geometry['x1']
    /// update data source with new Rect attributes
    data['x'].push(x);
    data['y'].push(y);
    data['width'].push(width);
    data['height'].push(height);
    data['eventType'] = 'none'
    data['leftEdge'] = leftEdge
    data['rightEdge'] = rightEdge
    // trigger update of data source
    source.trigger('change');
""")

tapCallback = bkM.CustomJS(args=dict(source=source), code=“”"

    // get data source from Callback args
    var data = source.get('data');
    var width = data['width']
    IPython.notebook.kernel.execute("leftEdge = " + data['leftEdge']);
    IPython.notebook.kernel.execute("rightEdge = "  + data['rightEdge'] );

""")

Need an identifier / pointer to the glyph. Once I have that, how to I remove the glpyh?

In [42]:

leftEdge =

rightEdge =

p = bkP.figure(width=800, height=350,x_range=[0,13], y_range=(0,2))

x = np.deg2rad(range(720))

y = 1+np.sin(x)

p.xaxis.axis_label = ‘time’

p.yaxis.axis_label = ‘position’

p.line(x,y,line_width=4,name=‘aLine’)

initRect = bkM.Rect(x=‘x’,

        y='y',
        width='width',
        height='height',
        fill_alpha=0.3,
        fill_color='gray')

notSelected = bkM.Rect(x=‘x’,

        y='y',
        width='width',
        height='height',
        fill_alpha=0.3,
        fill_color='gray')

selected = bkM.Rect(x=‘x’,

        y='y',
        width='width',
        height='height',
        fill_alpha=0.3,
        fill_color='green')

p.add_glyph(source, initRect, selection_glyph=selected, nonselection_glyph=notSelected,name=‘rect’)

p.add_tools(bkM.BoxSelectTool(dimensions=[“width”],callback=boxCallback))

p.add_tools(bkM.TapTool(callback=tapCallback))

bkP.show(p)

Out[42]:

<Bokeh Notebook handle for In[42]>

In [44]:

from ipywidgets import *

from IPython.display import display

def foundSacc(sender):

print leftEdge
print rightEdge

b2 = Button(description=‘Fixation’,value=False)

b2.on_click(foundSacc)

b2.width = ‘20%’

b1 = Button(description=‘Saccade’,value=False)

b1.on_click(foundSacc)

b1.width = ‘20%’

display(b1,b2)

×

Saccade

Fixation

In :

from future import division

import pandas as pd

import numpy as np

import bokeh.plotting as bkP

import bokeh.models as bkM

from bokeh.palettes import Spectral6

from bokeh.embed import file_html

from bokeh.resources import CDN

bkP.output_notebook()

source = bkM.ColumnDataSource(data=dict(x=, y=, width=, height=,leftEdge=,rightEdge=))

boxCallback = bkM.CustomJS(args=dict(source=source), code=“”"

    // get data source from Callback args
    var data = source.get('data');

    /// get BoxSelectTool dimensions from cb_data parameter of Callback
    var geometry = cb_data['geometry'];

    /// calculate Rect attributes
    var width = geometry['x1'] - geometry['x0'];
    var height = geometry['y1'] - geometry['y0'];
    var x = geometry['x0'] + width/2;
    var y = geometry['y0'] + height/2;
    var leftEdge = geometry['x0']
    var rightEdge = geometry['x1']
    /// update data source with new Rect attributes
    data['x'].push(x);
    data['y'].push(y);
    data['width'].push(width);
    data['height'].push(height);
    data['eventType'] = 'none'
    data['leftEdge'] = leftEdge
    data['rightEdge'] = rightEdge
    // trigger update of data source
    source.trigger('change');
""")

tapCallback = bkM.CustomJS(args=dict(source=source), code=“”"

    // get data source from Callback args
    var data = source.get('data');
    var width = data['width']
    IPython.notebook.kernel.execute("leftEdge = " + data['leftEdge']);
    IPython.notebook.kernel.execute("rightEdge = "  + data['rightEdge'] );

""")

IPython.notebook.kernel.execute("leftEdge = width + " + data[‘x’]);

IPython.notebook.kernel.execute("rightEdge = width " + data[‘x’] );

leftEdge =

rightEdge =

p = bkP.figure(width=800, height=350,x_range=[0,13], y_range=(0,2))

x = np.deg2rad(range(720))

y = 1+np.sin(x)

p.xaxis.axis_label = ‘time’

p.yaxis.axis_label = ‘position’

p.line(x,y,line_width=4,name=‘aLine’)

initRect = bkM.Rect(x=‘x’,

        y='y',
        width='width',
        height='height',
        fill_alpha=0.3,
        fill_color='gray')

notSelected = bkM.Rect(x=‘x’,

        y='y',
        width='width',
        height='height',
        fill_alpha=0.3,
        fill_color='gray')

selected = bkM.Rect(x=‘x’,

        y='y',
        width='width',
        height='height',
        fill_alpha=0.3,
        fill_color='green')

p.add_glyph(source, initRect, selection_glyph=selected, nonselection_glyph=notSelected,name=‘rect’)

p.add_tools(bkM.BoxSelectTool(dimensions=[“width”],callback=boxCallback))

p.add_tools(bkM.TapTool(callback=tapCallback))

bkP.show(p)

########################################################################

########################################################################

NewCell

from ipywidgets import *

from IPython.display import display

def foundSacc(sender):

print leftEdge
print rightEdge

b2 = Button(description=‘Fixation’,value=False)

b2.on_click(foundSacc)

b2.width = ‘20%’

b1 = Button(description=‘Saccade’,value=False)

b1.on_click(foundSacc)

b1.width = ‘20%’

display(b1,b2)

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/b0400249-fb53-482c-8768-c2134923b72a%40continuum.io.

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

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/F270D184-4A4D-42BE-BD0C-D1B5D77CF158%40continuum.io.

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


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/CAFvLWO2nWKTTZ_Ybjpkb7RcP215hbS1SLzy6Osoyd5j8KCV%2B_w%40mail.gmail.com.

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

Hi,

This is a very long thread, and almost two years old. I don’t really recall the context and it’s not clear to me what you are asking. I’d suggest making a brand new post to ask your question with full details.

Thanks,

Bryan

···

On Apr 7, 2018, at 07:49, 2014BIT046 AVINASH NARAYAN MAGAR [email protected] wrote:

Hi,
I read your answer as per below. You explained very well here. You mentioned 3 ways here. However I would like to employ first approach in my project . Can you provide me any example on how to recreate new plot at the same location in layout as that of old plot.

Thanks,
Avinash

On Thursday, June 9, 2016 at 7:38:50 PM UTC+5:30, Bryan Van de ven wrote:

Hi,

Bokeh is a library that spans (at least) two languages and runtime environments, which can sometimes be confusing. Looking at your code, I see you are updating data sources in a JS callback. This only affects the JavaScript data source object in the JavaScript runtime, and will have no reflection into the python space normally. If you need the python/JS to stay “in sync” with one another, that is the primary purpose of the Bokeh server. However, work to make the Bokeh server integrate with the notebook is still ongoing.

However, there are other options for keeping the JS and python objects in sync, namely the “push_notebook” function that was demonstrated in the notebooks I linked earlier. This function allows you to make changes to the python objects (for instance, the glyphs and data sources that you have created) and then have those changes update an existing plot in a notebook cell. Right now this update only happens in one direction: from Python → JS, although there are other folks interested in and working on ideas to enable the “reverse” direction updates as well.

Regarding where to find the glyphs, do you mean on the python side? Or on the JS side? On the python side you you are creating the glyphs and adding them with .add_glyph, you can just use the reference to the glyph you created? Or when you create with, e.g. fig.circle(…) that fucntion returns the glyph renderer, just store it in a variable if you need to use it. Technically, glyph renderers are stored in the .renderers property of Plots, but I would not recommend rooting around there by hand. Specifically the “Continuous Updating” notebook I linked earlier has an example of updating both the data and appearance of an existing glyph using python and push_notebook. This sounds like what you were asking for? There is not any easy way to remove glyphs at the moment, other options would be:

  • recreate a new plot

  • set the glyph to be invisble

  • update the glyphs data

Perhaps it would help to back away from specific implementation questions, because it may be the case that there is some other better path or approach. Can you describe what you are trying to accomplish, at a higher level, without referring to any potential implementation details? That is, more like “I want to have this sort of plot, that shows this kind of data, and these three widgets. When a button is pushed, I want such and such to happen”.

Thanks,

Bryan

On Jun 9, 2016, at 7:54 AM, Gabriel Diaz [email protected] wrote:

Thanks Bryan. Unless I missed it, I don’t see an answer to my question in those otherwise very helpful guides.

Let me try and restate my issue, in case it lacked clarity (that large code dump didn’t help!). I am adding new glyphs to my figure through modification of a column datasource within a javascript callback function. I would subsequently like to access, manipulate, and perhaps remove these glyphs through ipywidget callbacks, using Python.

However, I cannot find where information about individual glpyhs objects stored.

The callback I use is a modified version of the reference example on callbacks for box select. My intuition was that this callback is manipulating the column datasource, which was accumulating the information of multiple glyphs. However, even when multiple ‘rects’ have been added to my figure, the columnData source, when accessed through Python, remains empty. Perhaps I need to invoke the Python kernel from within the JS callback function to return the modified source to the Python workspace?

I’ve explored all the related Bokeh objects, and have done due diligence looking for this answer elsewhere, without luck.

Thanks

  • gD

Gabriel J. Diaz, Ph.D.

Assistant Professor

Rochester Institute of Technology

Chester F. Carlson Center for Imaging Science

Founder of PerForM Labs

Click for demos.

Office 2108, Building #76

Rochester, NY 14623

Office: (585) 475-6215

gabrie…@rit.edu

On Wed, Jun 8, 2016 at 7:26 PM, Bryan Van de Ven [email protected] wrote:

I would suggest studying the examples here:

    [https://github.com/bokeh/bokeh/tree/master/examples/howto/notebook_comms](https://github.com/bokeh/bokeh/tree/master/examples/howto/notebook_comms)

Thanks,

Bryan

On Jun 8, 2016, at 4:13 PM, Gabriel Diaz [email protected] wrote:

Apologies. An example is included in the attached *.ipynb

  • gD

On Wednesday, June 8, 2016 at 5:12:17 PM UTC-4, Gabriel Diaz wrote:

Hello! I’m looking for a way a way to access the glyphs once they have been added to the figure. Upon access, I will need to change visual attributes, and, potentially, to remove the glyph from the figure. Note that the glyphs will be added interactively, through a callback function using the box select tool.

Code from my notebook is pasted below!

If you want to know more, read more to find out why…

Thanks!

  • gD

My goal is to create a somewhat robust tool for that students can use to label events in a time-series. The eventual goal is that they will use box-selection to mark a region, and use one of several ipywidget buttons that will…

  • Label the patch as event type A,B, or C (depending upon the button pressed)
  • Record the event type and start/stop time (on X) of the event in a pandas dataframe
  • Update the glyph to color-code the event

I would also like to provide the user the ability to remove a selected glyph from the dataframe and figure.

Example Event Labeller Last Checkpoint: 5 minutes ago (autosaved)

Python 2

  • File
  • Edit
  • View
  • Insert
  • Cell
  • Kernel
  • Help

CodeMarkdownRaw NBConvertHeading

CellToolbar

In [1]:

from future import division

import pandas as pd

import numpy as np

import bokeh.plotting as bkP

import bokeh.models as bkM

from bokeh.palettes import Spectral6

from bokeh.embed import file_html

from bokeh.resources import CDN

bkP.output_notebook()

x

from future import division

import pandas as pd

import numpy as np

import bokeh.plotting as bkP

import bokeh.models as bkM

from bokeh.palettes import Spectral6

from bokeh.embed import file_html

from bokeh.resources import CDN

bkP.output_notebook()

/Users/diaz/anaconda/lib/python2.7/site-packages/pandas/computation/init.py:19: UserWarning: The installed version of numexpr 2.4.4 is not supported in pandas and will be not be used

UserWarning)

BokehJS successfully loaded

In [41]:

x

source = bkM.ColumnDataSource(data=dict(x=, y=, width=, height=,leftEdge=,rightEdge=))

boxCallback = bkM.CustomJS(args=dict(source=source), code=“”"

    // get data source from Callback args
    var data = source.get('data');

    /// get BoxSelectTool dimensions from cb_data parameter of Callback
    var geometry = cb_data['geometry'];

    /// calculate Rect attributes
    var width = geometry['x1'] - geometry['x0'];
    var height = geometry['y1'] - geometry['y0'];
    var x = geometry['x0'] + width/2;
    var y = geometry['y0'] + height/2;
    var leftEdge = geometry['x0']
    var rightEdge = geometry['x1']
    /// update data source with new Rect attributes
    data['x'].push(x);
    data['y'].push(y);
    data['width'].push(width);
    data['height'].push(height);
    data['eventType'] = 'none'
    data['leftEdge'] = leftEdge
    data['rightEdge'] = rightEdge
    // trigger update of data source
    source.trigger('change');
""")

tapCallback = bkM.CustomJS(args=dict(source=source), code=“”"

    // get data source from Callback args
    var data = source.get('data');
    var width = data['width']
    IPython.notebook.kernel.execute("leftEdge = " + data['leftEdge']);
    IPython.notebook.kernel.execute("rightEdge = "  + data['rightEdge'] );

""")

Need an identifier / pointer to the glyph. Once I have that, how to I remove the glpyh?

In [42]:

leftEdge =

rightEdge =

p = bkP.figure(width=800, height=350,x_range=[0,13], y_range=(0,2))

x = np.deg2rad(range(720))

y = 1+np.sin(x)

p.xaxis.axis_label = ‘time’

p.yaxis.axis_label = ‘position’

p.line(x,y,line_width=4,name=‘aLine’)

initRect = bkM.Rect(x=‘x’,

        y='y',
        width='width',
        height='height',
        fill_alpha=0.3,
        fill_color='gray')

notSelected = bkM.Rect(x=‘x’,

        y='y',
        width='width',
        height='height',
        fill_alpha=0.3,
        fill_color='gray')

selected = bkM.Rect(x=‘x’,

        y='y',
        width='width',
        height='height',
        fill_alpha=0.3,
        fill_color='green')

p.add_glyph(source, initRect, selection_glyph=selected, nonselection_glyph=notSelected,name=‘rect’)

p.add_tools(bkM.BoxSelectTool(dimensions=[“width”],callback=boxCallback))

p.add_tools(bkM.TapTool(callback=tapCallback))

bkP.show(p)

Out[42]:

<Bokeh Notebook handle for In[42]>

In [44]:

from ipywidgets import *

from IPython.display import display

def foundSacc(sender):

print leftEdge
print rightEdge

b2 = Button(description=‘Fixation’,value=False)

b2.on_click(foundSacc)

b2.width = ‘20%’

b1 = Button(description=‘Saccade’,value=False)

b1.on_click(foundSacc)

b1.width = ‘20%’

display(b1,b2)

×

Saccade

Fixation

In :

from future import division

import pandas as pd

import numpy as np

import bokeh.plotting as bkP

import bokeh.models as bkM

from bokeh.palettes import Spectral6

from bokeh.embed import file_html

from bokeh.resources import CDN

bkP.output_notebook()

source = bkM.ColumnDataSource(data=dict(x=, y=, width=, height=,leftEdge=,rightEdge=))

boxCallback = bkM.CustomJS(args=dict(source=source), code=“”"

    // get data source from Callback args
    var data = source.get('data');

    /// get BoxSelectTool dimensions from cb_data parameter of Callback
    var geometry = cb_data['geometry'];

    /// calculate Rect attributes
    var width = geometry['x1'] - geometry['x0'];
    var height = geometry['y1'] - geometry['y0'];
    var x = geometry['x0'] + width/2;
    var y = geometry['y0'] + height/2;
    var leftEdge = geometry['x0']
    var rightEdge = geometry['x1']
    /// update data source with new Rect attributes
    data['x'].push(x);
    data['y'].push(y);
    data['width'].push(width);
    data['height'].push(height);
    data['eventType'] = 'none'
    data['leftEdge'] = leftEdge
    data['rightEdge'] = rightEdge
    // trigger update of data source
    source.trigger('change');
""")

tapCallback = bkM.CustomJS(args=dict(source=source), code=“”"

    // get data source from Callback args
    var data = source.get('data');
    var width = data['width']
    IPython.notebook.kernel.execute("leftEdge = " + data['leftEdge']);
    IPython.notebook.kernel.execute("rightEdge = "  + data['rightEdge'] );

""")

IPython.notebook.kernel.execute("leftEdge = width + " + data[‘x’]);

IPython.notebook.kernel.execute("rightEdge = width " + data[‘x’] );

leftEdge =

rightEdge =

p = bkP.figure(width=800, height=350,x_range=[0,13], y_range=(0,2))

x = np.deg2rad(range(720))

y = 1+np.sin(x)

p.xaxis.axis_label = ‘time’

p.yaxis.axis_label = ‘position’

p.line(x,y,line_width=4,name=‘aLine’)

initRect = bkM.Rect(x=‘x’,

        y='y',
        width='width',
        height='height',
        fill_alpha=0.3,
        fill_color='gray')

notSelected = bkM.Rect(x=‘x’,

        y='y',
        width='width',
        height='height',
        fill_alpha=0.3,
        fill_color='gray')

selected = bkM.Rect(x=‘x’,

        y='y',
        width='width',
        height='height',
        fill_alpha=0.3,
        fill_color='green')

p.add_glyph(source, initRect, selection_glyph=selected, nonselection_glyph=notSelected,name=‘rect’)

p.add_tools(bkM.BoxSelectTool(dimensions=[“width”],callback=boxCallback))

p.add_tools(bkM.TapTool(callback=tapCallback))

bkP.show(p)

########################################################################

########################################################################

NewCell

from ipywidgets import *

from IPython.display import display

def foundSacc(sender):

print leftEdge
print rightEdge

b2 = Button(description=‘Fixation’,value=False)

b2.on_click(foundSacc)

b2.width = ‘20%’

b1 = Button(description=‘Saccade’,value=False)

b1.on_click(foundSacc)

b1.width = ‘20%’

display(b1,b2)

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/b0400249-fb53-482c-8768-c2134923b72a%40continuum.io.

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

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/F270D184-4A4D-42BE-BD0C-D1B5D77CF158%40continuum.io.

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


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/CAFvLWO2nWKTTZ_Ybjpkb7RcP215hbS1SLzy6Osoyd5j8KCV%2B_w%40mail.gmail.com.

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

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/191b9fad-3553-464a-a9d5-8478c36aee20%40continuum.io.

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