Get all models by name in Bokeh 2.2.3

Is there a way to get all models in curdoc() by name without specifying the name?

I am giving each line a unique name:

def movingAveragePlot(n, df, fig):
    for i in range(len(n)):
        ma = dp.movingAverage(n[i], df['Close'])
        #name is ma + n, eg: "ma50", "ma100" etc
        line = fig.line(ma.index, ma, line_width = 0.5, color = 'red', name="ma"+str(n[i]))
        fig.add_tools(HoverTool(
        renderers=[line],
        tooltips=[
            ("MA: ", str(n[i]))
        ],
        mode='vline'
        ))

I want to turn off their visibility at click of a button but I cannot figure out how to get all model names present in curdoc().

My current workaround (Spaghetti Code):

for i in range(0, 501):
    try:
        line = curdoc().get_model_by_name('ma'+str(i))
        line.visible = False
    except Exception:
        continue

Does anyone have a better workaround for this?

Why am I not using multi_line?
Because HoverTool is broken for multi_line in 2.2.3 [BUG]multi_line doesn’t support hover.
Also, I found there is just one HoverTool displayed for a multi_line instead of separate HoverTools for all lines in multi_line, once I downgraded the Bokeh version to 2.1.0

@MarineBiologist This is definitely different from the use-cases that motivated having a name property in the first place (e.g. looking up one or two data sources or glyphs) and no one has ever asked about it before. AFAIK no API for getting all the names has ever been added. I would say the best solution is simply to keep track of all the names you add, e.g by adding them to a Python set() as you add them. Then you can just iterate over the set of known names directly.

1 Like

Thanks, I got it working with your suggestion.

For future someone coming across a similar problem, this is how I got it working

def handleVisibility(glyphName, flag):
    isPresent = False
    for item in glyphsSet:
        if (glyphName in item):
            isPresent = True
            if (flag == 'visible'):
                curdoc().get_model_by_name(item).visible = True
            elif (flag == 'invisible'):
                curdoc().get_model_by_name(item).visible = False
    return isPresent

glyphName is setting name of the glyph (refer first post for eg: "ma" + str(n[i]))
and glyphsSet is maintaining a set of glyphName. glyphsSet should be declared globally i.e. outside all methods so it is visible to all methods and maintains concurrency.