I’m using Bokeh (0.12.14) to build a dashboard (standalone app rather than in a Jupyter notebook) that allows flexible selection of a subset of rows from a pandas dataframe. For that, I’m using RadioButtonGroup and CheckboxButtonGroup selectors, depending on the columns based on which I want to select my data. I have a list of such widgets in a column layout. To manipulate these selectors, I change labels and active for them via an on_change() callback. For some of these selectors, clicking and selecting works fine. However, in other cases (e.g., when there is only one label) I attempt to programmatically set active=0 and notice that the updated widgets do not show up on the screen. Accidentally, I’ve noticed that they actually show up immediately after I resize my browser window; they show up selected (i.e. selected label is highlighted), as expected. To be clear, in my on_change()**, ** I currently don’t modify layout object (passed to curdoc().add_root()) directly but rather update the properties of existing widget (layout’s children); I’ve tried to experiment with replacing layout.children with updated widgets, as described below, but that adds noticeable flickering.
The code is fairly complicated to be shared as is (includes custom classes that handle dataframe manipulation and selector interactions). I can try to put together a minimal example if my description and questions do not help to get on the right track.
My immediate questions (hopefully, specific enough) are:
So far, I’ve tried inside on_change():
layout.children = 
for s in list_of_my_selector_objects:
Is there a better way of doing this that helps reduce flickering?
I’ve run into something that I didn’t expect with my on_change() callback. Inside it, I modify active on the currently modified selector and go into a loop where I update all the following widgets: update their labels based on the current selection. As part of this, if one of the following selectors has only one label, I “auto” select it by modifying active for that selector. As I’ve learned from my logs, this triggers another on_change()and I end up with an update loop running inside an update loop. I can avoid this undesirable behavior (e.g. with a global flag being_updated) and exit early from this inner/secondary loop. This is exactly the case where my widgets don’t show up on the screen until I resize the browser window. I wonder if I’m missing anything in processing this interaction, and if anyone has any comments or recommendations on handling it properly.
Finally, I’ve looked into using curdoc().on_change(callback). I can register a custom callback and it will be called every time one of the widget is modified, but I don’t know what to put in there for revealing those “hidden” widgets. Is there a way to “refresh” the page?
I’ll appreciate any comments, suggestions, and code references.
P.S. I’ve been enjoying working with Bokeh so far. It does exactly what I need for creating sophisticated, interactive plots; however, this dynamic, progressive reveal for selectors connected to a dataframe is a bit difficult to get right. I’m trying to make my code general and flexible enough to make it available at the end, when it is reliable. If there are any existing efforts or relevant considerations, please let me know.