Columndatasource not in document puzzle when using a JS/Notebook callback combination

Hello,

Recently updated to 0.13.0 and seem to be running into an issue when trying to use a JS / Python Callback combination attached to the Jupyter Notebook server. I’ve attached a notebook, but for clarities sake, the code is also below. This is intended to be run in Jupyter Notebook.

The objective of the code is to have a JS Callback attached to the x_range and y_range which contains the dimensions of the plot and will update a ColumnDataSource ‘dims’ each time the plot ranges change. The JS code contains a throttle to limit the frequency of callbacks when zooming (this is not my code and has been taken from an example I have since lost track of).

‘dims’ will in turn trigger a python callback which will handle some larger plot changes.

I cannot get the latter python callback to trigger, as everytime I zoom on the plot, I receive the following console error:

VM64 bokeh-0.13.0.min.js:31 Uncaught Error: reference {“id”:“0c0b6f42-4dbb-46e0-9684-c1cb28a23369”,“type”:“ColumnDataSource”} isn’t known (not in Document?)

at o (VM64 bokeh-0.13.0.min.js:31)

at VM64 bokeh-0.13.0.min.js:31

at o (VM64 bokeh-0.13.0.min.js:31)

at Function.P._resolve_refs (VM64 bokeh-0.13.0.min.js:31)

at P.apply_json_patch (VM64 bokeh-0.13.0.min.js:31)

at t._handle_patch (VM64 bokeh-0.13.0.min.js:31)

at t.handle (VM64 bokeh-0.13.0.min.js:31)

at t._steady_state_handler (VM64 bokeh-0.13.0.min.js:31)

at t.ACK.t.msgtype._current_handler (VM64 bokeh-0.13.0.min.js:31)

at t._on_message (VM64 bokeh-0.13.0.min.js:31)

``

The “id” above is referring to the dims Columndatasource object, but I cannot see why it is not considered part of the document (previously I have had this code running effectively with 0.12.6).

Code is below (MVE)

import bokeh.plotting as bk

from bokeh.models import ColumnDataSource, CustomJS

from bokeh.application.handlers import FunctionHandler

from bokeh.application import Application

import numpy as np

bk.output_notebook()

``

class TestPlot():

def init(self):

self.x_range = np.arange(100)

self.y_range = np.arange(100)

self.width = 100

self.height = 100

self.dims = ColumnDataSource(data=dict(width=[self.width],

height=[self.height],

xmin=[self.x_range.min()],

xmax=[self.x_range.max()],

ymin=[self.y_range.max()],

ymax=[self.y_range.min()]))

self.dims_jscode = “”"

var update_dims = function () {

var new_data = {

height: [plot.plot_height],

width: [plot.plot_width],

xmin: [plot.x_range.start],

ymin: [plot.y_range.start],

xmax: [plot.x_range.end],

ymax: [plot.y_range.end]

};

dims.data = new_data;

};

if (typeof throttle != ‘undefined’ && throttle != null) {

clearTimeout(throttle);

}

throttle = setTimeout(update_dims, 100, “replace”);

“”"

self.dims.on_change(‘data’, self.on_dims_change)

self.figure = bk.figure(x_range = (self.x_range.min(),

self.x_range.max()),

y_range = (self.y_range.max(),

self.y_range.min()))

self.figure.x_range.callback = CustomJS(code=self.dims_jscode,

args=dict(plot=self.figure,

dims=self.dims))

self.figure.y_range.callback = CustomJS(code=self.dims_jscode,

args=dict(plot=self.figure,

dims=self.dims))

self.figure.line(np.arange(100), 0.5*np.arange(100))

def on_dims_change(self, attr, old, new):

print(self.dims.data)

def modify_doc(self, doc):

doc.add_root(self.figure)

bk.curdoc().clear()

p = TestPlot()

handler = FunctionHandler(p.modify_doc)

app = Application(handler)

bk.show(app)

``

Any thoughts would be much appreciated!

Kind regards,
George

JupyterCallbackError.ipynb (23.2 KB)

Hi,

First of all, please note that things have been simplified, you can now simply define a function

  def modify_doc(doc):

and pass that directly to show:

  show(modify_doc)

There is no need to create your own Application or FunctionHandler normally.

As to your specific case, the issue is that, whatever function is provided to be called to modify the doc, that function has to create *everything completely new every time*. You are creating a CDS in the __init__ of your class, and calling that once before passing a function to show. That is not allowed. Every session must have its own unique set of Bokeh objects. It is not possible to "share" Bokeh objects between different sessions. You need to create the CDS (and every bokeh object) inside the same function that calls "doc.add_root(...)"

Bryan

···

On Sep 5, 2018, at 15:56, George Crowther <[email protected]> wrote:

Hello,

Recently updated to 0.13.0 and seem to be running into an issue when trying to use a JS / Python Callback combination attached to the Jupyter Notebook server. I've attached a notebook, but for clarities sake, the code is also below. This is intended to be run in Jupyter Notebook.

The objective of the code is to have a JS Callback attached to the x_range and y_range which contains the dimensions of the plot and will update a ColumnDataSource 'dims' each time the plot ranges change. The JS code contains a throttle to limit the frequency of callbacks when zooming (this is not my code and has been taken from an example I have since lost track of).
'dims' will in turn trigger a python callback which will handle some larger plot changes.
I cannot get the latter python callback to trigger, as everytime I zoom on the plot, I receive the following console error:
VM64 bokeh-0.13.0.min.js:31 Uncaught Error: reference {"id":"0c0b6f42-4dbb-46e0-9684-c1cb28a23369","type":"ColumnDataSource"} isn't known (not in Document?)
    at o (VM64 bokeh-0.13.0.min.js:31)
    at VM64 bokeh-0.13.0.min.js:31
    at o (VM64 bokeh-0.13.0.min.js:31)
    at Function.P._resolve_refs (VM64 bokeh-0.13.0.min.js:31)
    at P.apply_json_patch (VM64 bokeh-0.13.0.min.js:31)
    at t._handle_patch (VM64 bokeh-0.13.0.min.js:31)
    at t.handle (VM64 bokeh-0.13.0.min.js:31)
    at t._steady_state_handler (VM64 bokeh-0.13.0.min.js:31)
    at t.ACK.t.msgtype._current_handler (VM64 bokeh-0.13.0.min.js:31)
    at t._on_message (VM64 bokeh-0.13.0.min.js:31)

The "id" above is referring to the dims Columndatasource object, but I cannot see why it is not considered part of the document (previously I have had this code running effectively with 0.12.6).

Code is below (MVE)
import bokeh.plotting as bk
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.application.handlers import FunctionHandler
from bokeh.application import Application

import numpy as np

bk.output_notebook()

class TestPlot():
    
    def __init__(self):
        
        self.x_range = np.arange(100)
        self.y_range = np.arange(100)
        self.width = 100
        self.height = 100
        
        self.dims = ColumnDataSource(data=dict(width=[self.width],
                                               height=[self.height],
                                               xmin=[self.x_range.min()],
                                               xmax=[self.x_range.max()],
                                               ymin=[self.y_range.max()],
                                               ymax=[self.y_range.min()]))
        
        self.dims_jscode = """
            var update_dims = function () {
                var new_data = {
                    height: [plot.plot_height],
                    width: [plot.plot_width],
                    xmin: [plot.x_range.start],
                    ymin: [plot.y_range.start],
                    xmax: [plot.x_range.end],
                    ymax: [plot.y_range.end]
                };
                dims.data = new_data;
            };
            if (typeof throttle != 'undefined' && throttle != null) {
                clearTimeout(throttle);
            }
            throttle = setTimeout(update_dims, 100, "replace");
            """
        self.dims.on_change('data', self.on_dims_change)
        self.figure = bk.figure(x_range = (self.x_range.min(),
                                           self.x_range.max()),
                                y_range = (self.y_range.max(),
                                           self.y_range.min()))
        self.figure.x_range.callback = CustomJS(code=self.dims_jscode,
                                                args=dict(plot=self.figure,
                                                          dims=self.dims))
        self.figure.y_range.callback = CustomJS(code=self.dims_jscode,
                                                args=dict(plot=self.figure,
                                                          dims=self.dims))
        self.figure.line(np.arange(100), 0.5*np.arange(100))
        
    def on_dims_change(self, attr, old, new):
        print(self.dims.data)

    def modify_doc(self, doc):
        doc.add_root(self.figure)

bk.curdoc().clear()
p = TestPlot()
handler = FunctionHandler(p.modify_doc)
app = Application(handler)
bk.show(app)

Any thoughts would be much appreciated!

Kind regards,
George

--
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/74bd13f5-446c-45ed-a059-1b1b6f9c48a5%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.
<JupyterCallbackError.ipynb>

Thanks Bryan,

Is the need for the bokeh objects to be declared in the function passed to curdoc().add_root imposed by the JS callback? I’ve been writing applications based around this architecture for nearly a year using only python callbacks, and this one specifically has worked until 0.13.0 (though I appreciate that this is likely more by luck that judgement on my part). My purely python based jupyter bokeh applets do not complain about ColumnDataSources being created in the init when running in 0.13.0.

Thanks for the help,

George

···

On Thursday, 6 September 2018 19:58:02 UTC+1, Bryan Van de ven wrote:

Hi,

First of all, please note that things have been simplified, you can now simply define a function

    def modify_doc(doc):

and pass that directly to show:

    show(modify_doc)

There is no need to create your own Application or FunctionHandler normally.

As to your specific case, the issue is that, whatever function is provided to be called to modify the doc, that function has to create everything completely new every time. You are creating a CDS in the init of your class, and calling that once before passing a function to show. That is not allowed. Every session must have its own unique set of Bokeh objects. It is not possible to “share” Bokeh objects between different sessions. You need to create the CDS (and every bokeh object) inside the same function that calls “doc.add_root(…)”

Bryan

On Sep 5, 2018, at 15:56, George Crowther [email protected] wrote:

Hello,

Recently updated to 0.13.0 and seem to be running into an issue when trying to use a JS / Python Callback combination attached to the Jupyter Notebook server. I’ve attached a notebook, but for clarities sake, the code is also below. This is intended to be run in Jupyter Notebook.

The objective of the code is to have a JS Callback attached to the x_range and y_range which contains the dimensions of the plot and will update a ColumnDataSource ‘dims’ each time the plot ranges change. The JS code contains a throttle to limit the frequency of callbacks when zooming (this is not my code and has been taken from an example I have since lost track of).

‘dims’ will in turn trigger a python callback which will handle some larger plot changes.

I cannot get the latter python callback to trigger, as everytime I zoom on the plot, I receive the following console error:

VM64 bokeh-0.13.0.min.js:31 Uncaught Error: reference {“id”:“0c0b6f42-4dbb-46e0-9684-c1cb28a23369”,“type”:“ColumnDataSource”} isn’t known (not in Document?)

at o (VM64 bokeh-0.13.0.min.js:31)
at VM64 bokeh-0.13.0.min.js:31
at o (VM64 bokeh-0.13.0.min.js:31)
at Function.P._resolve_refs (VM64 bokeh-0.13.0.min.js:31)
at P.apply_json_patch (VM64 bokeh-0.13.0.min.js:31)
at t._handle_patch (VM64 bokeh-0.13.0.min.js:31)
at t.handle (VM64 bokeh-0.13.0.min.js:31)
at t._steady_state_handler (VM64 bokeh-0.13.0.min.js:31)
at t.ACK.t.msgtype._current_handler (VM64 bokeh-0.13.0.min.js:31)
at t._on_message (VM64 bokeh-0.13.0.min.js:31)

The “id” above is referring to the dims Columndatasource object, but I cannot see why it is not considered part of the document (previously I have had this code running effectively with 0.12.6).

Code is below (MVE)

import bokeh.plotting as bk

from bokeh.models import ColumnDataSource, CustomJS

from bokeh.application.handlers import FunctionHandler

from bokeh.application import Application

import numpy as np

bk.output_notebook()

class TestPlot():

def __init__(self):
    self.x_range = np.arange(100)
    self.y_range = np.arange(100)
    self.width = 100
    self.height = 100
    self.dims = ColumnDataSource(data=dict(width=[self.width],
                                           height=[self.height],
                                           xmin=[self.x_range.min()],
                                           xmax=[self.x_range.max()],
                                           ymin=[self.y_range.max()],
                                           ymax=[self.y_range.min()]))
    self.dims_jscode = """
        var update_dims = function () {
            var new_data = {
                height: [plot.plot_height],
                width: [plot.plot_width],
                xmin: [plot.x_range.start],
                ymin: [plot.y_range.start],
                xmax: [plot.x_range.end],
                ymax: [plot.y_range.end]
            };
            dims.data = new_data;
        };
        if (typeof throttle != 'undefined' && throttle != null) {
            clearTimeout(throttle);
        }
        throttle = setTimeout(update_dims, 100, "replace");
        """
    self.dims.on_change('data', self.on_dims_change)
    self.figure = bk.figure(x_range = (self.x_range.min(),
                                       self.x_range.max()),
                            y_range = (self.y_range.max(),
                                       self.y_range.min()))
    self.figure.x_range.callback = CustomJS(code=self.dims_jscode,
                                            args=dict(plot=self.figure,
                                                      dims=self.dims))
    self.figure.y_range.callback = CustomJS(code=self.dims_jscode,
                                            args=dict(plot=self.figure,
                                                      dims=self.dims))
    self.figure.line(np.arange(100), 0.5*np.arange(100))
def on_dims_change(self, attr, old, new):
    print(self.dims.data)
def modify_doc(self, doc):
    doc.add_root(self.figure)

bk.curdoc().clear()

p = TestPlot()

handler = FunctionHandler(p.modify_doc)

app = Application(handler)

bk.show(app)

Any thoughts would be much appreciated!

Kind regards,

George


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/74bd13f5-446c-45ed-a059-1b1b6f9c48a5%40continuum.io.

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

<JupyterCallbackError.ipynb>

Hi,

No, it has nothing to do with the JS callback. It has always been the case that Bokeh models cannot be shared between different documents/sessions, and doing so has generated a runtime exception for as long as I can recall. It's not really possible to speculate much about things without actual code to run. I can only say that the error is only triggered once a model that is already in a document, is attempted to be added to a second document. (It has nothing to do with being in an __init__, specifically, in case that was not clear) So if, e.g. in the notebook you are only ever showing the app once, you would never see any error, because any models would only get added to that single document, for the single session.

Thanks,

Bryan

···

On Sep 9, 2018, at 14:15, George Crowther <[email protected]> wrote:

Thanks Bryan,

Is the need for the bokeh objects to be declared in the function passed to curdoc().add_root imposed by the JS callback? I've been writing applications based around this architecture for nearly a year using only python callbacks, and this one specifically has worked until 0.13.0 (though I appreciate that this is likely more by luck that judgement on my part). My purely python based jupyter bokeh applets do not complain about ColumnDataSources being created in the __init__ when running in 0.13.0.

Thanks for the help,
George

On Thursday, 6 September 2018 19:58:02 UTC+1, Bryan Van de ven wrote:
Hi,

First of all, please note that things have been simplified, you can now simply define a function

        def modify_doc(doc):

and pass that directly to show:

        show(modify_doc)

There is no need to create your own Application or FunctionHandler normally.

As to your specific case, the issue is that, whatever function is provided to be called to modify the doc, that function has to create *everything completely new every time*. You are creating a CDS in the __init__ of your class, and calling that once before passing a function to show. That is not allowed. Every session must have its own unique set of Bokeh objects. It is not possible to "share" Bokeh objects between different sessions. You need to create the CDS (and every bokeh object) inside the same function that calls "doc.add_root(...)"

Bryan

> On Sep 5, 2018, at 15:56, George Crowther <[email protected]> wrote:
>
> Hello,
>
> Recently updated to 0.13.0 and seem to be running into an issue when trying to use a JS / Python Callback combination attached to the Jupyter Notebook server. I've attached a notebook, but for clarities sake, the code is also below. This is intended to be run in Jupyter Notebook.
>
> The objective of the code is to have a JS Callback attached to the x_range and y_range which contains the dimensions of the plot and will update a ColumnDataSource 'dims' each time the plot ranges change. The JS code contains a throttle to limit the frequency of callbacks when zooming (this is not my code and has been taken from an example I have since lost track of).
> 'dims' will in turn trigger a python callback which will handle some larger plot changes.
> I cannot get the latter python callback to trigger, as everytime I zoom on the plot, I receive the following console error:
> VM64 bokeh-0.13.0.min.js:31 Uncaught Error: reference {"id":"0c0b6f42-4dbb-46e0-9684-c1cb28a23369","type":"ColumnDataSource"} isn't known (not in Document?)
> at o (VM64 bokeh-0.13.0.min.js:31)
> at VM64 bokeh-0.13.0.min.js:31
> at o (VM64 bokeh-0.13.0.min.js:31)
> at Function.P._resolve_refs (VM64 bokeh-0.13.0.min.js:31)
> at P.apply_json_patch (VM64 bokeh-0.13.0.min.js:31)
> at t._handle_patch (VM64 bokeh-0.13.0.min.js:31)
> at t.handle (VM64 bokeh-0.13.0.min.js:31)
> at t._steady_state_handler (VM64 bokeh-0.13.0.min.js:31)
> at t.ACK.t.msgtype._current_handler (VM64 bokeh-0.13.0.min.js:31)
> at t._on_message (VM64 bokeh-0.13.0.min.js:31)
>
> The "id" above is referring to the dims Columndatasource object, but I cannot see why it is not considered part of the document (previously I have had this code running effectively with 0.12.6).
>
> Code is below (MVE)
> import bokeh.plotting as bk
> from bokeh.models import ColumnDataSource, CustomJS
> from bokeh.application.handlers import FunctionHandler
> from bokeh.application import Application
>
> import numpy as np
>
> bk.output_notebook()
>
> class TestPlot():
>
> def __init__(self):
>
> self.x_range = np.arange(100)
> self.y_range = np.arange(100)
> self.width = 100
> self.height = 100
>
> self.dims = ColumnDataSource(data=dict(width=[self.width],
> height=[self.height],
> xmin=[self.x_range.min()],
> xmax=[self.x_range.max()],
> ymin=[self.y_range.max()],
> ymax=[self.y_range.min()]))
>
> self.dims_jscode = """
> var update_dims = function () {
> var new_data = {
> height: [plot.plot_height],
> width: [plot.plot_width],
> xmin: [plot.x_range.start],
> ymin: [plot.y_range.start],
> xmax: [plot.x_range.end],
> ymax: [plot.y_range.end]
> };
> dims.data = new_data;
> };
> if (typeof throttle != 'undefined' && throttle != null) {
> clearTimeout(throttle);
> }
> throttle = setTimeout(update_dims, 100, "replace");
> """
> self.dims.on_change('data', self.on_dims_change)
> self.figure = bk.figure(x_range = (self.x_range.min(),
> self.x_range.max()),
> y_range = (self.y_range.max(),
> self.y_range.min()))
> self.figure.x_range.callback = CustomJS(code=self.dims_jscode,
> args=dict(plot=self.figure,
> dims=self.dims))
> self.figure.y_range.callback = CustomJS(code=self.dims_jscode,
> args=dict(plot=self.figure,
> dims=self.dims))
> self.figure.line(np.arange(100), 0.5*np.arange(100))
>
> def on_dims_change(self, attr, old, new):
> print(self.dims.data)
>
> def modify_doc(self, doc):
> doc.add_root(self.figure)
>
> bk.curdoc().clear()
> p = TestPlot()
> handler = FunctionHandler(p.modify_doc)
> app = Application(handler)
> bk.show(app)
>
> Any thoughts would be much appreciated!
>
> Kind regards,
> George
>
> --
> 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 bokeh+un...@continuum.io.
> To post to this group, send email to bo...@continuum.io.
> To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/74bd13f5-446c-45ed-a059-1b1b6f9c48a5%40continuum.io\.
> For more options, visit https://groups.google.com/a/continuum.io/d/optout\.
> <JupyterCallbackError.ipynb>

--
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/71e64eee-494a-4128-8604-47b03a60e3de%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Hi George,

I recently face a very similar problem. What was your workaround? I keep getting the element with id something is not known in document error. When I downgrade though, the problems resolve. But I don’t want to downgrade the version

Thanks,

Baran.

···

On Monday, September 10, 2018 at 12:15:47 AM UTC+3, George Crowther wrote:

Thanks Bryan,

Is the need for the bokeh objects to be declared in the function passed to curdoc().add_root imposed by the JS callback? I’ve been writing applications based around this architecture for nearly a year using only python callbacks, and this one specifically has worked until 0.13.0 (though I appreciate that this is likely more by luck that judgement on my part). My purely python based jupyter bokeh applets do not complain about ColumnDataSources being created in the init when running in 0.13.0.

Thanks for the help,

George

On Thursday, 6 September 2018 19:58:02 UTC+1, Bryan Van de ven wrote:

Hi,

First of all, please note that things have been simplified, you can now simply define a function

    def modify_doc(doc):

and pass that directly to show:

    show(modify_doc)

There is no need to create your own Application or FunctionHandler normally.

As to your specific case, the issue is that, whatever function is provided to be called to modify the doc, that function has to create everything completely new every time. You are creating a CDS in the init of your class, and calling that once before passing a function to show. That is not allowed. Every session must have its own unique set of Bokeh objects. It is not possible to “share” Bokeh objects between different sessions. You need to create the CDS (and every bokeh object) inside the same function that calls “doc.add_root(…)”

Bryan

On Sep 5, 2018, at 15:56, George Crowther [email protected] wrote:

Hello,

Recently updated to 0.13.0 and seem to be running into an issue when trying to use a JS / Python Callback combination attached to the Jupyter Notebook server. I’ve attached a notebook, but for clarities sake, the code is also below. This is intended to be run in Jupyter Notebook.

The objective of the code is to have a JS Callback attached to the x_range and y_range which contains the dimensions of the plot and will update a ColumnDataSource ‘dims’ each time the plot ranges change. The JS code contains a throttle to limit the frequency of callbacks when zooming (this is not my code and has been taken from an example I have since lost track of).

‘dims’ will in turn trigger a python callback which will handle some larger plot changes.

I cannot get the latter python callback to trigger, as everytime I zoom on the plot, I receive the following console error:

VM64 bokeh-0.13.0.min.js:31 Uncaught Error: reference {“id”:“0c0b6f42-4dbb-46e0-9684-c1cb28a23369”,“type”:“ColumnDataSource”} isn’t known (not in Document?)

at o (VM64 bokeh-0.13.0.min.js:31)
at VM64 bokeh-0.13.0.min.js:31
at o (VM64 bokeh-0.13.0.min.js:31)
at Function.P._resolve_refs (VM64 bokeh-0.13.0.min.js:31)
at P.apply_json_patch (VM64 bokeh-0.13.0.min.js:31)
at t._handle_patch (VM64 bokeh-0.13.0.min.js:31)
at t.handle (VM64 bokeh-0.13.0.min.js:31)
at t._steady_state_handler (VM64 bokeh-0.13.0.min.js:31)
at t.ACK.t.msgtype._current_handler (VM64 bokeh-0.13.0.min.js:31)
at t._on_message (VM64 bokeh-0.13.0.min.js:31)

The “id” above is referring to the dims Columndatasource object, but I cannot see why it is not considered part of the document (previously I have had this code running effectively with 0.12.6).

Code is below (MVE)

import bokeh.plotting as bk

from bokeh.models import ColumnDataSource, CustomJS

from bokeh.application.handlers import FunctionHandler

from bokeh.application import Application

import numpy as np

bk.output_notebook()

class TestPlot():

def __init__(self):
    self.x_range = np.arange(100)
    self.y_range = np.arange(100)
    self.width = 100
    self.height = 100
    self.dims = ColumnDataSource(data=dict(width=[self.width],
                                           height=[self.height],
                                           xmin=[self.x_range.min()],
                                           xmax=[self.x_range.max()],
                                           ymin=[self.y_range.max()],
                                           ymax=[self.y_range.min()]))
    self.dims_jscode = """
        var update_dims = function () {
            var new_data = {
                height: [plot.plot_height],
                width: [plot.plot_width],
                xmin: [plot.x_range.start],
                ymin: [plot.y_range.start],
                xmax: [plot.x_range.end],
                ymax: [plot.y_range.end]
            };
            dims.data = new_data;
        };
        if (typeof throttle != 'undefined' && throttle != null) {
            clearTimeout(throttle);
        }
        throttle = setTimeout(update_dims, 100, "replace");
        """
    self.dims.on_change('data', self.on_dims_change)
    self.figure = bk.figure(x_range = (self.x_range.min(),
                                       self.x_range.max()),
                            y_range = (self.y_range.max(),
                                       self.y_range.min()))
    self.figure.x_range.callback = CustomJS(code=self.dims_jscode,
                                            args=dict(plot=self.figure,
                                                      dims=self.dims))
    self.figure.y_range.callback = CustomJS(code=self.dims_jscode,
                                            args=dict(plot=self.figure,
                                                      dims=self.dims))
    self.figure.line(np.arange(100), 0.5*np.arange(100))
def on_dims_change(self, attr, old, new):
    print(self.dims.data)
def modify_doc(self, doc):
    doc.add_root(self.figure)

bk.curdoc().clear()

p = TestPlot()

handler = FunctionHandler(p.modify_doc)

app = Application(handler)

bk.show(app)

Any thoughts would be much appreciated!

Kind regards,

George


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/74bd13f5-446c-45ed-a059-1b1b6f9c48a5%40continuum.io.

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

<JupyterCallbackError.ipynb>