New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new child to existing column #5518

Closed
mrocklin opened this Issue Dec 7, 2016 · 18 comments

Comments

Projects
None yet
8 participants
@mrocklin
Contributor

mrocklin commented Dec 7, 2016

When adding a child plot to an existing column and then updating the plot appears but then I get the following error:

bokeh.server.protocol.server_handler - ERROR - error handling message Message 'PATCH-DOC' (revision 1): RuntimeError('Cannot apply patch to 8cf5ddd0-9b96-49fc-8099-c792733d0ff5 which is not in the document',)

And my figures come out wonky:

image

 
    def __init__(...):
        ...
        self.sizing_mode = 'scale_width'
        self.figures = {}
        self.sources = {}
        self.root = column(sizing_mode=self.sizing_mode)

    def add_figure(self, name):
        source = ColumnDataSource({'x': [], 'y': []})
        fig = figure(title=name, tools='', height=150, sizing_mode=self.sizing_mode)
        fig.line(source=source, x='x', y='y')
        self.sources[name] = source
        self.figures[name] = fig
        self.root.children = self.root.children + [fig]

    def update(self):
        for name, counter in self.server.counters.items():
            if name not in self.figures:
                self.add_figure(name)
            else:
                xs = [counter.quantile(i / 100) for i in range(101)]
                ys = [xs[i + 1] - xs[i] for i in range(len(xs) - 1)]
                self.sources[name].data.update({'x': xs, 'y': ys})
@mattpap

This comment has been minimized.

Show comment
Hide comment
@mattpap

mattpap Dec 7, 2016

Contributor

That error is unexpected. Failing on layout is something that would normally happen. Layout, as currently implemented, doesn't like changes.

Contributor

mattpap commented Dec 7, 2016

That error is unexpected. Failing on layout is something that would normally happen. Layout, as currently implemented, doesn't like changes.

@mrocklin

This comment has been minimized.

Show comment
Hide comment
@mrocklin

mrocklin Dec 7, 2016

Contributor

I'm also fine with a "this is not supported" answer. I can find ways around this if necessary.

Contributor

mrocklin commented Dec 7, 2016

I'm also fine with a "this is not supported" answer. I can find ways around this if necessary.

@bryevdv

This comment has been minimized.

Show comment
Hide comment
@bryevdv

bryevdv Dec 7, 2016

Member

It should be supported, we've always intended to have a second pass to shore up some rough edges around layout there just have not been resources to do it yet.

Member

bryevdv commented Dec 7, 2016

It should be supported, we've always intended to have a second pass to shore up some rough edges around layout there just have not been resources to do it yet.

@mattpap

This comment has been minimized.

Show comment
Hide comment
@mattpap

mattpap Dec 7, 2016

Contributor

I'm also fine with a "this is not supported" answer.

No, 'PATCH-DOC' (revision 1): RuntimeError('Cannot apply patch (...)') always indicates a bug in core bokeh's (or bokehjs') infrastructure (or around it, e.g. API allowing data structures not supported down the chain).

Contributor

mattpap commented Dec 7, 2016

I'm also fine with a "this is not supported" answer.

No, 'PATCH-DOC' (revision 1): RuntimeError('Cannot apply patch (...)') always indicates a bug in core bokeh's (or bokehjs') infrastructure (or around it, e.g. API allowing data structures not supported down the chain).

@bryevdv

This comment has been minimized.

Show comment
Hide comment
@bryevdv

bryevdv Dec 7, 2016

Member

Yes, the protocol is supposed to afford adding new models, not just patching existing ones.

Member

bryevdv commented Dec 7, 2016

Yes, the protocol is supposed to afford adding new models, not just patching existing ones.

@azjps

This comment has been minimized.

Show comment
Hide comment
@azjps

azjps Jan 6, 2017

Contributor

Encountered similar issue, although was not adding a new figure but instead adding a new completely unrelated DOM element. This apparently causes the constraint solver to fail, but only when certain other models like figures are in the document.

Here's a minimal reproducible example:

from bokeh.layouts import column
from bokeh.models.widgets import (Button, Div)
from bokeh.models.sources import ColumnDataSource
from bokeh.plotting import curdoc, figure

source = ColumnDataSource(data={"x": [0], "y": [0]})
fig = figure(plot_width=500, plot_height=300)
fig.circle(x="x", y="y", source=source)
button = Button(label="Add point")

column1 = column([fig,
                  button])
column2 = column([])

counter = 0 
def on_click():
  global counter
  counter += 1 
  source.stream({"x": [counter], "y": [counter]})
  column2.children = [Div(text=str(counter))]  # new, completely unrelated, element

button.on_click(on_click)

curdoc().add_root(column([column1, column2]))

When you click on the button, it gives a JS error:

Uncaught Error: unknown constraint
    at Solver.removeConstraint (bokeh.js:46936)
    at Solver.exports.Solver.Solver.remove_constraint (bokeh.js:2324)
    at Object.exports.update_constraints (bokeh.js:2158)
    at PlotCanvasView.exports.PlotCanvasView.PlotCanvasView.update_constraints (bokeh.js:18141)
    at PlotCanvasView.exports.PlotCanvasView.PlotCanvasView.render (bokeh.js:18079)
    at later (bokeh.js:4381)

Note that no error arises however if either

  • The figure is removed from the example
  • The unrelated layout is not updated in on_click

I recall reading a related issue which suggested that there could be issues with changing the children of a layout, unfortunately I can't find that issue ticket right now. I forget though if its a todo or a won't-do; if the latter it would not be possible to say have a dynamic number of plots, which would be a blocking issue for me.

Contributor

azjps commented Jan 6, 2017

Encountered similar issue, although was not adding a new figure but instead adding a new completely unrelated DOM element. This apparently causes the constraint solver to fail, but only when certain other models like figures are in the document.

Here's a minimal reproducible example:

from bokeh.layouts import column
from bokeh.models.widgets import (Button, Div)
from bokeh.models.sources import ColumnDataSource
from bokeh.plotting import curdoc, figure

source = ColumnDataSource(data={"x": [0], "y": [0]})
fig = figure(plot_width=500, plot_height=300)
fig.circle(x="x", y="y", source=source)
button = Button(label="Add point")

column1 = column([fig,
                  button])
column2 = column([])

counter = 0 
def on_click():
  global counter
  counter += 1 
  source.stream({"x": [counter], "y": [counter]})
  column2.children = [Div(text=str(counter))]  # new, completely unrelated, element

button.on_click(on_click)

curdoc().add_root(column([column1, column2]))

When you click on the button, it gives a JS error:

Uncaught Error: unknown constraint
    at Solver.removeConstraint (bokeh.js:46936)
    at Solver.exports.Solver.Solver.remove_constraint (bokeh.js:2324)
    at Object.exports.update_constraints (bokeh.js:2158)
    at PlotCanvasView.exports.PlotCanvasView.PlotCanvasView.update_constraints (bokeh.js:18141)
    at PlotCanvasView.exports.PlotCanvasView.PlotCanvasView.render (bokeh.js:18079)
    at later (bokeh.js:4381)

Note that no error arises however if either

  • The figure is removed from the example
  • The unrelated layout is not updated in on_click

I recall reading a related issue which suggested that there could be issues with changing the children of a layout, unfortunately I can't find that issue ticket right now. I forget though if its a todo or a won't-do; if the latter it would not be possible to say have a dynamic number of plots, which would be a blocking issue for me.

@bryevdv

This comment has been minimized.

Show comment
Hide comment
@bryevdv

bryevdv Jan 6, 2017

Member

Thanks for the test case, just FYI resolving this is one of my top two priorities for 0.12.5

Member

bryevdv commented Jan 6, 2017

Thanks for the test case, just FYI resolving this is one of my top two priorities for 0.12.5

@azjps

This comment has been minimized.

Show comment
Hide comment
@azjps

azjps Jan 6, 2017

Contributor

Thanks, good to know. (also figured it'd be helpful to have the JS error pasted above so that it could be searched for in the issue tracker.)

Contributor

azjps commented Jan 6, 2017

Thanks, good to know. (also figured it'd be helpful to have the JS error pasted above so that it could be searched for in the issue tracker.)

@mattpap mattpap added this to the 0.12.5 milestone Jan 6, 2017

@mattpap mattpap self-assigned this Jan 6, 2017

@mattpap

This comment has been minimized.

Show comment
Hide comment
@mattpap

mattpap Feb 21, 2017

Contributor

I tried to reproduce the original issue on top of master and I wasn't able. Perhaps this issue may depend on how bokeh server is used. @mrocklin, can you provide a complete setup for the snipped you gave earlier?

Contributor

mattpap commented Feb 21, 2017

I tried to reproduce the original issue on top of master and I wasn't able. Perhaps this issue may depend on how bokeh server is used. @mrocklin, can you provide a complete setup for the snipped you gave earlier?

@mattpap

This comment has been minimized.

Show comment
Hide comment
@mattpap

mattpap Feb 21, 2017

Contributor

@azjps' issue is something different and easily reproducible. Also, replacing widgets with plots gives you different kinds of errors (e.g. unknown edit variable).

Contributor

mattpap commented Feb 21, 2017

@azjps' issue is something different and easily reproducible. Also, replacing widgets with plots gives you different kinds of errors (e.g. unknown edit variable).

@pstoeckl

This comment has been minimized.

Show comment
Hide comment
@pstoeckl

pstoeckl Feb 22, 2017

Came across a similar issue, so am chiming in here with another toy example in case it proves useful. Clicking 'Replace Plot', then 'Expand Range', will trigger the same 'unknown constraint' error reported above:

from bokeh.layouts import row, column
from bokeh.models.sources import ColumnDataSource
from bokeh.models.widgets import Button
from bokeh.plotting import figure, curdoc

x = range(0,13)
y = range(2,15)
circ = ColumnDataSource(dict(x=[0,1],y=[0,1]))

fig = figure(y_axis_type='log')
fig.line(x,y)
fig2 = figure()
fig2.circle(x='x',y='y',source=circ)

but = Button(label="Replace Plot")
but2 = Button(label="Expand Range")

c = column(but, but2, fig, fig2)

def replace_plot():
    fig3 = figure(y_axis_type='linear')
    fig3.line(x,y)
    c.children[2] = fig3

def expand_range():
    circ.data['y'] = [0, 5001]

but.on_click(replace_plot)
but2.on_click(expand_range)

curdoc().add_root(c)

Differences to the previous example:

  • here, a figure is replaced rather than added
  • the triggering condition is a dynamic plot range update

Similarly to the previous example, the error also occurs if replace_plot adds a new figure instead, but does not occur if replace_plot is never called. (Tested on Bokeh 0.12.4 via bokeh serve.)

pstoeckl commented Feb 22, 2017

Came across a similar issue, so am chiming in here with another toy example in case it proves useful. Clicking 'Replace Plot', then 'Expand Range', will trigger the same 'unknown constraint' error reported above:

from bokeh.layouts import row, column
from bokeh.models.sources import ColumnDataSource
from bokeh.models.widgets import Button
from bokeh.plotting import figure, curdoc

x = range(0,13)
y = range(2,15)
circ = ColumnDataSource(dict(x=[0,1],y=[0,1]))

fig = figure(y_axis_type='log')
fig.line(x,y)
fig2 = figure()
fig2.circle(x='x',y='y',source=circ)

but = Button(label="Replace Plot")
but2 = Button(label="Expand Range")

c = column(but, but2, fig, fig2)

def replace_plot():
    fig3 = figure(y_axis_type='linear')
    fig3.line(x,y)
    c.children[2] = fig3

def expand_range():
    circ.data['y'] = [0, 5001]

but.on_click(replace_plot)
but2.on_click(expand_range)

curdoc().add_root(c)

Differences to the previous example:

  • here, a figure is replaced rather than added
  • the triggering condition is a dynamic plot range update

Similarly to the previous example, the error also occurs if replace_plot adds a new figure instead, but does not occur if replace_plot is never called. (Tested on Bokeh 0.12.4 via bokeh serve.)

@bryevdv

This comment has been minimized.

Show comment
Hide comment
@bryevdv

bryevdv Feb 26, 2017

Member

@mattpap just FYI I think some things I'm recording in #4875 might have some (at least tnagential) bearing here. You should merge in the array intersection fix at the very least, since caused problems when new models were added. But see also the comments about attach_document in the other issue. Those changes alone don't fix this issue, but they might be necessary preconditions.

Member

bryevdv commented Feb 26, 2017

@mattpap just FYI I think some things I'm recording in #4875 might have some (at least tnagential) bearing here. You should merge in the array intersection fix at the very least, since caused problems when new models were added. But see also the comments about attach_document in the other issue. Those changes alone don't fix this issue, but they might be necessary preconditions.

@bryevdv

This comment has been minimized.

Show comment
Hide comment
@bryevdv

bryevdv Apr 26, 2017

Member

@azjps example was fixed by #5976 but there is still some follow on work to get @pstoeckl example working as well, so leaving open for now.

Member

bryevdv commented Apr 26, 2017

@azjps example was fixed by #5976 but there is still some follow on work to get @pstoeckl example working as well, so leaving open for now.

@philippjfr

This comment has been minimized.

Show comment
Hide comment
@philippjfr

philippjfr May 15, 2017

Contributor

Seeing the same issue in a condition similar to @pstoeckl's example using bokeh 0.12.6dev4, it all seems to work despite the errors though.

Contributor

philippjfr commented May 15, 2017

Seeing the same issue in a condition similar to @pstoeckl's example using bokeh 0.12.6dev4, it all seems to work despite the errors though.

@mattpap

This comment has been minimized.

Show comment
Hide comment
@mattpap

mattpap May 15, 2017

Contributor

@philippjfr, because those errors come from views that aren't relevant anymore, but weren't destroyed yet.

Contributor

mattpap commented May 15, 2017

@philippjfr, because those errors come from views that aren't relevant anymore, but weren't destroyed yet.

@bryevdv

This comment has been minimized.

Show comment
Hide comment
@bryevdv

bryevdv Jun 1, 2017

Member

I think this might also be related to #4810 (same PATCH-DOC error messages)

Also, confirming still an issue as of 0.12.6dev7

Member

bryevdv commented Jun 1, 2017

I think this might also be related to #4810 (same PATCH-DOC error messages)

Also, confirming still an issue as of 0.12.6dev7

@dantamont

This comment has been minimized.

Show comment
Hide comment
@dantamont

dantamont Dec 8, 2017

Has this issue been resolved? I am encountering the same error when trying to replace a row in my layout with some new widgets.

dantamont commented Dec 8, 2017

Has this issue been resolved? I am encountering the same error when trying to replace a row in my layout with some new widgets.

@RobMulla

This comment has been minimized.

Show comment
Hide comment
@RobMulla

RobMulla Jan 18, 2018

I'm also experiencing this issue.

My version of python and bokeh:

>>> import sys
>>> import bokeh
>>> print(sys.version)
3.6.4 |Anaconda, Inc.| (default, Jan 16 2018, 12:04:33)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]
>>> print(bokeh.__version__)
0.12.13

This is a simplified version of the main.py that creates the error.

from bokeh.io import curdoc
from bokeh.layouts import row, column, widgetbox
from bokeh.models.widgets import Slider, TextInput, Button
from bokeh.plotting import figure
from bokeh.models.widgets import Panel, Tabs


def query_prop_data():
    # Query data goes in here
    tab1_plots.children[0] = figure(plot_height=500,
                                    plot_width=1000,
                                    title='QUERY PLOT DONE')
    tab2_plots.children[0] = figure(plot_height=500,
                                    plot_width=1000,
                                    title='QUERY PLOT DONE')
    return


def refresh_plots():
    # Refresh Plot goes in here
    tab1_plots.children[0] = figure(plot_height=500,
                                    plot_width=1000,
                                    title='PLOT REFRESHED')
    return


def update(attr, old, new):
    refresh_plots()
    return


# Setup Widgets
window = Slider(title="Change only tab 1", value=0, start=0, end=35, step=7)
prop_txt = TextInput(placeholder='enter prop code', title='PROPERTY CODE:')
run_button = Button(label='Query', button_type='success')

for widget in [window]:
    widget.on_change('value', update)

for widget in [run_button]:
    widget.on_click(query_prop_data)

inputs = widgetbox(prop_txt, run_button, window)

tab1_plots = row(column())
tab2_plots = row(column())

tab1_plots.children[0] = figure(plot_height=500,
                                plot_width=1000,
                                title='QUERY A PROPERTY TO GENERATE PLOT')
tab2_plots.children[0] = figure(plot_height=500,
                                plot_width=1000,
                                title='QUERY A PROPERTY TO GENERATE PLOT')


tab1 = Panel(child=tab1_plots, title="Tab1")
tab2 = Panel(child=tab2_plots, title="Tab2")

tabs = Tabs(tabs=[tab1, tab2], width=1000)
page_layout = row(children=[inputs, tabs], sizing_mode='fixed')

curdoc().add_root(page_layout)
curdoc().title = "Forecast Analysis"

Only occurs when query_prop_data is called (by clicking the Button)

I start up my server with
$bokeh serve --show bokehtest

Each time the query button is clicked I get four lines like this:

2018-01-18 13:48:51,357 Cannot apply patch to aa41f426-0641-4ddf-b418-f0c92bcd3d24 which is not in the document anymore
2018-01-18 13:48:51,359 Cannot apply patch to aa41f426-0641-4ddf-b418-f0c92bcd3d24 which is not in the document anymore
2018-01-18 13:48:51,360 Cannot apply patch to aa41f426-0641-4ddf-b418-f0c92bcd3d24 which is not in the document anymore
2018-01-18 13:48:51,361 Cannot apply patch to aa41f426-0641-4ddf-b418-f0c92bcd3d24 which is not in the document anymore

Not sure if this is a code issue on my part or a bug. Hope that helps!

RobMulla commented Jan 18, 2018

I'm also experiencing this issue.

My version of python and bokeh:

>>> import sys
>>> import bokeh
>>> print(sys.version)
3.6.4 |Anaconda, Inc.| (default, Jan 16 2018, 12:04:33)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]
>>> print(bokeh.__version__)
0.12.13

This is a simplified version of the main.py that creates the error.

from bokeh.io import curdoc
from bokeh.layouts import row, column, widgetbox
from bokeh.models.widgets import Slider, TextInput, Button
from bokeh.plotting import figure
from bokeh.models.widgets import Panel, Tabs


def query_prop_data():
    # Query data goes in here
    tab1_plots.children[0] = figure(plot_height=500,
                                    plot_width=1000,
                                    title='QUERY PLOT DONE')
    tab2_plots.children[0] = figure(plot_height=500,
                                    plot_width=1000,
                                    title='QUERY PLOT DONE')
    return


def refresh_plots():
    # Refresh Plot goes in here
    tab1_plots.children[0] = figure(plot_height=500,
                                    plot_width=1000,
                                    title='PLOT REFRESHED')
    return


def update(attr, old, new):
    refresh_plots()
    return


# Setup Widgets
window = Slider(title="Change only tab 1", value=0, start=0, end=35, step=7)
prop_txt = TextInput(placeholder='enter prop code', title='PROPERTY CODE:')
run_button = Button(label='Query', button_type='success')

for widget in [window]:
    widget.on_change('value', update)

for widget in [run_button]:
    widget.on_click(query_prop_data)

inputs = widgetbox(prop_txt, run_button, window)

tab1_plots = row(column())
tab2_plots = row(column())

tab1_plots.children[0] = figure(plot_height=500,
                                plot_width=1000,
                                title='QUERY A PROPERTY TO GENERATE PLOT')
tab2_plots.children[0] = figure(plot_height=500,
                                plot_width=1000,
                                title='QUERY A PROPERTY TO GENERATE PLOT')


tab1 = Panel(child=tab1_plots, title="Tab1")
tab2 = Panel(child=tab2_plots, title="Tab2")

tabs = Tabs(tabs=[tab1, tab2], width=1000)
page_layout = row(children=[inputs, tabs], sizing_mode='fixed')

curdoc().add_root(page_layout)
curdoc().title = "Forecast Analysis"

Only occurs when query_prop_data is called (by clicking the Button)

I start up my server with
$bokeh serve --show bokehtest

Each time the query button is clicked I get four lines like this:

2018-01-18 13:48:51,357 Cannot apply patch to aa41f426-0641-4ddf-b418-f0c92bcd3d24 which is not in the document anymore
2018-01-18 13:48:51,359 Cannot apply patch to aa41f426-0641-4ddf-b418-f0c92bcd3d24 which is not in the document anymore
2018-01-18 13:48:51,360 Cannot apply patch to aa41f426-0641-4ddf-b418-f0c92bcd3d24 which is not in the document anymore
2018-01-18 13:48:51,361 Cannot apply patch to aa41f426-0641-4ddf-b418-f0c92bcd3d24 which is not in the document anymore

Not sure if this is a code issue on my part or a bug. Hope that helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment