ERROR:bokeh.core.validation.check:E-1027 (REPEATED_LAYOUT_CHILD)

I am attempting to have a variable number of figures depened on the number of columns in a dataframe. The attached code works but still plots and functions fine. What am I doing incorrectly to throw an error?

Thanks for any help

Error:
ERROR:bokeh.core.validation.check:E-1027 (REPEATED_LAYOUT_CHILD): The same model can’t be used multiple times in a layout: Column(id=‘p1145’

Code:

import pandas as pd
from bokeh.palettes import Category20_20, inferno
from bokeh.layouts import layout, column, row
import datetime
from datetime import datetime, timedelta, date
import bokeh.plotting
import bokeh.layouts
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, Legend

data = [{'a': 1, 'b': 2, 'c': 3},{'a': 10, 'b': 20, 'c': 30},{'a': 20, 'b': 30, 'c': 50},{'a': 30 ,'b': 40, 'c': 90}]
dfM = pd.DataFrame(data)
plots = []
source = dfM
CL =1;colors = iter(Category20_20)
p = figure(title='test',sizing_mode="stretch_width",toolbar_location='right')

PlotStep = 1;LineLimiter = 2;count = 0
for col in dfM:
    if count < LineLimiter:
        if col != 'TimeStep':      
            for r in range(LineLimiter+1):
                if CL== 20: # resets colors
                    colors = iter(Category20_20)
                    CL=1   
                p.line(x = dfM['a'], y = dfM[col], color=next(colors),legend_label=col)
                CL=CL+1
        plots.append(p)
        p.xaxis.ticker.desired_num_ticks = 20
        p.legend.click_policy="hide"
        count = count +1
    if count >= LineLimiter:
        count = 0
        PlotStep = PlotStep +1
        p = figure(title='test',
            sizing_mode="stretch_width",
            toolbar_location='right', 
            )
if PlotStep >1:
    LayOutR = column(*plots,sizing_mode="stretch_width")
else:
    LayOutR = column(plots,sizing_mode="stretch_width")
p.xaxis.axis_label = 'My X-axis'
p.yaxis.axis_label = 'My Y-axis'
p.legend.click_policy="hide"
p.legend.location = 'right'
p.xaxis.ticker.desired_num_ticks = 20

show(LayOutR,sizing_mode="stretch_width")

The error is referring to the situation:

p = figure(...)

layout = column(p, p) # same plot added more than once

In your code, you call plots.append(p) in a loop, which appears to result in adding the same plot more than once. Although it may “work” in whatever version you have installed, this is explicitly unsupported usage and may stop “working” at any time.

Thank you for the response.
I’m not a power user so be patient with me if you will.
I assume the layout(*plots) is equivalent to layout = column(p, p) in your reply?
Any advice on how to add an indeterminate number of plots? In my example if the number of columns in the dataframe exceed the desire number of lines I want on a plot (LineLimiter), a new plot will be generated and ultimately show the plots in a column. In the real application, I’d like to limit the lines on a single plot to 20 (LineLimiter =20) and I have 100 columns to plot. That would mean I the output would be 5 plots stacked in a column. Sorry if this is a bother, but I’ve attempted different numerous methods. The one I posted, sort of works but not safe for the future

It’s fine to have indeterminate number of plots, and it’s fine to collect all the plots in a loop as you are doing. There are several examples in the repo that do just this. The issue is that you are not creating a new plot every time you call plots.append(p) so are reusing a previous plot object that has already been added to plots. That is what you need to not do. Each individual plot object should only get appended once to the plots list.

Alternatively, after the loop is completely done, you could de-dupe the plots list before passing it to the layout. But it’s probably simpler to append the new plots to the plots list as soon as you call figure to create them. Then it should only get appened once.

Edit: just in case we have a terminology issue: each call to line is not a “plot”. A plot is the object created by the call to figure and each plot can have many lines or other glyphs.

I’ve done some searching in the Community Support area and yet to find an example. Either I’m not in the right area, or I don’t know what to search for. Any chance you can link me to one of the examples you are refering to just as a hint and educate?

Here is an example that collects plots in a loop:

https://github.com/bokeh/bokeh/blob/HEAD/examples/topics/geo/tile_demo.py

Notice that every iteration of the loop always creates a new plot, and then adds that new plot to the list, before the next iteration. There is no possibility that a plot gets added twice. This is not the case in your code (consider what happens if count < LineLimiter twice in a row—you’ll add the same plot from the previous iteration a second time).

Thank You Very Much. I see my error now. DUH!!

1 Like