Bokeh Breaks Randomly During Widget Change

I have been working with a multipage app (refer to this article in the documentation if you don’t understand what I mean). Each page has its own separate widgets which are effectively filters. When loading each of these pages and using these filters, it is almost as if the Bokeh gods decide if a filter will go through or if your server will break down.

Sometimes it is something quite reasonable (me saying this should give you an idea of how my experience with using Bokeh in non-traditional workflows has been) and I get an error like RuntimeError: _pending_writes should be non-None when we have a document lock, and we should have the lock when the document changes, to which all one has to do is just select the widget again and voila it works without any problem.

Sometimes, however, I get an error from Bokeh’s end, for something that has worked before that instead spits out AttributeError: 'Document' object has no attribute '_theme' and completely breaks the server, requiring a full shutdown and restart. For this example, by the way, all I did was hv.render([ANY Holoviews plot]) and as it goes down the execution chain to eventually Bokeh it breaks on Bokeh’s end.

This is completely unacceptable for production apps which sure might break but not on every run, and certainly not after maybe a few minutes of use. I am not sure how to address these kinds of issues and was hoping someone more experienced in the Holoviz community can lend a hand.

EDIT:
Something I forgot to add is that some of my Bokeh plots bound to a widget will eventually shrink to maybe a few pixels in height and stay that way no matter what widget value is chosen. Here is a small example, where the default value is using a “Day” interval:

I then select the “Month” one, so far so good:

Choosing exactly 1 more yields no problem, it can be any of the options. However, by the 4th time, I always get this:

I should note here that the title is actually a pn.pane.HTML for unrelated reasons, otherwise when it used to be part of the Bokeh plot it would disappear as well.

Now, for the life of my I cannot guess why this happens. To illustrate the above example and how odd it is, I have tried to store the chart by pn.bind-ing the widget to a plot function that would resample the dataset based on the value and return a pn.pane.Bokeh chart to be rendered. I would return the whole thing inside a pn.Column component. Later I figured it would be faster to have everything pre-rendered, so instead I set the values of the widget to the rendered plot() functions with the appropriate inputs, and instead changed my pn.bind from something like this pn.bind(plot,widget) to this pn.bind(lambda x: x, widget) since what widget would actually input was widget.value which was appropriately my plot.

Having tried these both and seeing it doesn’t necessarily have to do with the widget, but rather switching between Bokeh plots helps me realize this is actually a problem with Bokeh and not Panel. I have taken the time to raise this in Bokeh’s discourse but thought the Panel community would benefit from knowing such bugs exist. I unfortunately don’t know how to fix this, so if anyone has any advice it would greatly be appreciated.

Could you please link to the Bokeh forum post you mention?

Sure thing, here it is, although I will warn you there’s a lot repeated from this post.

This looks like the same error message I get randomly in my Panel Pipeline app. It started happening only on Ubuntu for me. Never seen it in windows.

Sometimes, however, I get an error from Bokeh’s end, for something that has worked before that instead spits out AttributeError: 'Document' object has no attribute '_theme' and completely breaks the server, requiring a full shutdown and restart. For this example, by the way, all I did was hv.render([ANY Holoviews plot]) and as it goes down the execution chain to eventually Bokeh it breaks on Bokeh’s end.

Can you provide a minimal example?

Also, to clarify, are you using Bokeh to serve or panel?

Other than that, maybe try setting a min height?

Sure I will write the plotting code below. I am using panel serve for deployment, and I tried setting min_height prior to calling hv.render, however the issue remained and the server still crashed. However I noticed a hack-ish method that works, which I will detail below:

Assume our data to plot is a timeseries and in a pandas DataFrame df, then the plotting code would be:

def plot():
    chart = df.hvplot.line(by="Year",
                            color=colors,
                            xformatter=bm.formatters.DatetimeTickFormatter(months="%b %Y",days="%b %d"),
                            xlabel="",
                            ylabel="",
                            tools=[hover,"box_zoom","wheel_zoom","tap"],
                            legend="top",
                            ).opts(
                                margin=(10,10),
                                border=0,
                                active_tools=["pan"],
                                padding=0.01,
                            )
    return chart

chart = plot()
chart = hv.render(chart) #breaks here

Now THIS would break, however if I were to put this in a try...except block and repeat the exact same function call, it works most of the time (except when a user goes back and forth between pages too much):

def plot():
    ...
chart = plot()
try:
    chart = hv.render(plot) # throws Exception
except:
    chart = hv.render(plot) # passes without further Exception

After scouring the Bokeh forums, Github issues, and some of the Github code, it seems there MIGHT be a bug that causes this. I am not sure how to fix this, nor would I say I am that inclined to at this point but hope this post helps someone out in the future.

P.S. I also want to say that most of my plotting frustrations in Panel have only sometimes been with the Panel codebase itself, and mostly with Bokeh. For comparison, whenever I used Altair/Vega I never ran into these kinds of issues, despite some more constraints I would say the user experience can be significantly smoother at times.

I filed a bug in the Panel issue tracker: Bokeh figure axes collapse on dynamic creation · Issue #5561 · holoviz/panel · GitHub

1 Like