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.