Tabs figure failure with webgl backend

bokeh version 2.0.2

I had a figure (with log y-axis) that was working fine, with webgl backend, and I put the figure into a tab, and created another figure (with linear y-axis), using the same source data. The second figure/tab is failing to draw properly, there are no y/x tics nor data plotted.

If I don’t use webgl backend the tab/figures render as expected, and there is no error in Chrome inspect.

If I “reload” the page, the figure in the tab will be rendered correctly, and the Chrome inspect error does not appear. There is no error.

In the Chrome inspect window I get this error (when the page is first loaded),

(anonymous) @ bokeh-2.0.2.min.js:469
(anonymous) @ bokeh-2.0.2.min.js:233
emit @ bokeh-2.0.2.min.js:176
emit @ bokeh-2.0.2.min.js:176
pywrapEventHandler @ land:805
land:42 {"caller":"doneEmit","redirect":null,"success":true}

land:1 [.WebGL-0x13419cd20800]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 2
bokeh-gl-2.0.2.min.js:62 Uncaught (in promise) RuntimeError: RuntimeError:OpenGL got errors (after draw): 1282
at u (http://192.168.86.36:6590/pywrapstatic/bokeh-gl-2.0.2.min.js:62:2760)
at a.draw (http://192.168.86.36:6590/pywrapstatic/bokeh-gl-2.0.2.min.js:62:9749)
at g.draw (http://192.168.86.36:6590/pywrapstatic/bokeh-gl-2.0.2.min.js:61:3234)
at g.render (http://192.168.86.36:6590/pywrapstatic/bokeh-gl-2.0.2.min.js:63:1268)
at render (http://192.168.86.36:6590/pywrapstatic/bokeh-2.0.2.min.js:254:1109)
at w.render (http://192.168.86.36:6590/pywrapstatic/bokeh-2.0.2.min.js:246:5763)
at k._paint_levels (http://192.168.86.36:6590/pywrapstatic/bokeh-2.0.2.min.js:469:16792)
at k.paint (http://192.168.86.36:6590/pywrapstatic/bokeh-2.0.2.min.js:469:16380)
at k.repaint (http://192.168.86.36:6590/pywrapstatic/bokeh-2.0.2.min.js:469:15262)
at http://192.168.86.36:6590/pywrapstatic/bokeh-2.0.2.min.js:469:3802
u @ bokeh-gl-2.0.2.min.js:62
a.draw @ bokeh-gl-2.0.2.min.js:62
draw @ bokeh-gl-2.0.2.min.js:61
render @ bokeh-gl-2.0.2.min.js:63

If I take the code and port it to a minimal example, everything works fine. The working minimal example looks like below, but it works.

from bokeh.layouts import layout, column, row, Spacer
from bokeh.io import show
from bokeh.models import Panel, Tabs
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource

source = ColumnDataSource(data={
    "t":  [-25, -24, -23,  -22,   -21],
    "i":  [  1,  10, 100, 1000, 10000],
})

source_trig = ColumnDataSource(data={
    "t":  [-25, 25],
    "i":  [ 10, 10],
})

x = (-25.0, 25.0)
fig_plot = figure(toolbar_location="above",
                  y_range=(0.1, 1000000),
                  x_range=x,
                  plot_width=600,
                  y_axis_type="log",
                  output_backend="webgl",
                  plot_height=600)

fig_plot_linear = figure(toolbar_location="above",
                         y_range=(0, 1000000),
                         x_range=x,
                         plot_width=600,
                         y_axis_type="linear",
                         output_backend="webgl",
                         plot_height=600)

line = fig_plot.line(x="t", y="i", line_width=2, source=source, color="green", legend_label="SRC")
line_linear = fig_plot_linear.line(x="t", y="i", line_width=2, source=source, color="green", legend_label="SRC")

tab1 = Panel(child=fig_plot, title="Log")
tab2 = Panel(child=fig_plot_linear, title="Linear")
tabs = Tabs(tabs=[tab1, tab2])

doc_layout = layout()
doc_layout.children.append(row([Spacer(width=10), column(Spacer(width=10), tabs)]))

show(doc_layout)

I have struggled to determine if I am doing something to cause the error. I have pretty much exhausted my ability to debug these types of errors (I am not a javascript programmer).

Maybe I can help get to the bottom of this if I get some hints on what to examine or try. My gut feeling is that there is some kind of race condition exposed from other things I am doing on this web page. I have tried to add things to the minimal example, making it closer to the real application, but I fail to find the culprit that causes the error.

My work around is just to turn off webgl.

Note the real application uses flask to serve up the page, and I use,

_script, _div = components(layout)

to create the page. I do have a minimal example of my environment but its too much to pass along. Needless to say I have added to that minimal to try and see what causes the error, but I have failed.

Yes, it means that either you’re doing something wrong in the real code or you’re using a perfectly fine workflow that has a bug in WebGL implementation.

Either way, I cannot say anything without seeing a version of the code that does break with WebGL. The only help I can offer right now is to advise you to make the minimal example be more similar to the real code by small incremental steps. And after each step see if you can reproduce the issue. Once you can, try to remove all other small bits till you’re no longer able to reproduce it, and then just return the last removed bit and post the code here.

Thank you. I did just that (again) and finally stumbled upon the issue.

The offending line was an event that replaced a column data source (CDS) from data that was only one point, to data that was two points. if I init that CDS with two points the error does not occur.

A little more detail. The CDS starts with this data,

plot_data_trig = {"t": [-2.5], "i": [0.001], "v": [0.001]}

After the page is loaded there is an event which updates the data to have two points,

plot_data_trig = {"t": [-2.5, 2.5], "i": [0.001, 0.001], "v": [0.001, 0.001]}

With webgl not enabled, there is no error and things are plotted as expected.

My fix was to init the data with two points (and re-enable the goodness of webgl).

I wish I could give you a minimal example but my code framework is a beast and you would hate to look at it. And I don’t know how to create an event with the minimal example with show() above.

Even if you change the minimal example above so that source_trig has only one point, that example will still work. It takes an update to the CDS to trigger the error.

Maybe it has been fixed already: [BUG] WebGL + CDSView seems to use incorrect marker fill colours · Issue #9230 · bokeh/bokeh · GitHub
You can check out the latest master or wait a bit will Bokeh 2.1 is released (should be in early June).