When replacing a plot with a variant copy that draws from the same DataSources as the original, a validation error preventing the replacement may inconsistently occur.
See the following minimal example:
from bokeh.layouts import column
from bokeh.models.widgets import Button
from bokeh.models.sources import ColumnDataSource
from bokeh.plotting import figure, curdoc
data1 = {‘x’: list(range(20,3020)), ‘y’: list(range(20,3020))}
data2 = {‘x’: list(range(20,3020)), ‘y’: list(range(50,3050))}
data3 = {‘x’: list(range(20,3020)), ‘y’: list(range(80,3080))}
source1 = ColumnDataSource(data=data1)
source2 = ColumnDataSource(data=data2)
source3 = ColumnDataSource(data=data3)
origplot = figure(plot_height=500, plot_width=600)
for src in [source1, source2, source3]:
origplot.line(‘x’,‘y’,source=src)
but = Button(label=“Change Y-Axis Type”)
col = column(origplot, but)
log = False
def replace_plot():
global log
log = not log
newplot = figure(plot_height=500, plot_width=600)
if log:
newplot.y_mapper_type = 'log'
for src in [source1, source2, source3]:
newplot.line('x','y',source=src)
col.children[0] = newplot
but.on_click(replace_plot)
curdoc().add_root(col)
``
Usually, clicking the button will replace the current plot with another showing the same data but with a different y-axis mapping (switching log for linear and vice-versa). Sometimes, however, the replacement fails, with the following error message in the console:
[bokeh] Error handling message: Error: Instance property ‘data_source’ given invalid value: [object Object], [object MessageEvent]
``
As this is fairly unhelpful, I dug down somewhat; the top portion of the stack trace runs as follows:
Prop.validate
exports.Property.Property._init
exports.Property.Property.update
exports.HasProps.HasProps.attach_document
exports.Document.Document._recompute_all_models
exports.Document.Document._invalidate_all_models
exports.LayoutDOMView.LayoutDOMView.build_child_views
triggerEvents
…
``
The value in question usually looks like
Object { id: “[long-id-string]”, type: “ColumnDataSource” }
``
at time of exception.
This seems to me like a bug; unfortunately its behavior is quite inconsistent - sometimes occurring on the first replacement, sometimes only after many.
The more DataSources or the larger the underlying data, the easier it has been to trip the error.
···
=============================
Additional Notes:
I have occasionally observed a similar error, but on Instance property ‘toolbar’ rather than ‘data_source’.
It appears that the error can be avoided by constructing new DataSources each time (rather than maintaining the old ones), e.g.
def replace_plot():
…
for data in [data1, data2, data3]:
src = ColumnDataSource(data=data)
newplot.line(‘x’,‘y’,source=src)
``
Behavior was observed on Chrome 56.0 and Firefox 47.0, the Bokeh app being run with bokeh serve (Bokeh 0.12.4 / Python 3.5.2).
