Unable to use column layout (and therefore range_tool) in Bokeh.js

Hello,

I’m a novice user in Bokeh and in web dev, and currently attempting to use BokehJS to draw graphs within an HTML file itself using data supplied from an API. (If that’s inadvisable, please let me know!)

My ultimate goal is to recreate the documentation example of range_tool in Bokeh.JS: range_tool — Bokeh 3.5.1 Documentation. In attempting to do so it seems to have two graphs using the same columnData I would have to use the column layout to avoid the “models must be owned by only a single document” error. Despite doing so, I consistently get the same error as shown below, which I am having trouble deciphering.

My original code is sort of a mess, so I attempted to pare down the issue to its barest essentials, ultimately creating two graphs and column data sources from scratch. If I display them in separate divs, both plots display successfully. However, attempting to join the two with Bokeh.Plotting.show(layout, document.getElementById("graph1")); always returns the error

"e.get is not a function.
    at l.initialize_props (bokeh-3.5.1.min.js:180:4405)
    at new x (bokeh-3.5.1.min.js:180:4262)
    at new u (bokeh-3.5.1.min.js:217:247)
    at new m (bokeh-3.5.1.min.js:250:1534)
    at new f (bokeh-3.5.1.min.js:277:3030)
    at new d (bokeh-3.5.1.min.js:582:1433)
    at new w (bokeh-3.5.1.min.js:581:7714)
    at new _ (bokeh-3.5.1.min.js:580:1558)
    at new l (bokeh-3.5.1.min.js:579:218)"

Here is my minimal code example:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bokeh Graphs Example</title>
    <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-3.5.1.min.js"></script>
    <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.1.min.js"></script>
    <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.1.min.js"></script>
    <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.1.min.js"></script>
    <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.5.1.min.js"></script>
    <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-api-3.5.1.min.js"></script>
    <link rel="stylesheet" href="https://cdn.bokeh.org/bokeh/release/bokeh-3.5.1.min.css" type="text/css" />
</head>
<body>

<div id="graph1" style="width: 600px; height: 400px;"></div>
<div id="graph2" style="width: 600px; height: 400px;"></div>

<script type="text/javascript">
    // Create the first graph
    const source1 = new Bokeh.ColumnDataSource({
        data: {
            x: [1, 2, 3, 4, 5],
            y: [6, 7, 2, 4, 5]
        }
    });

    const plot1 = new Bokeh.Plotting.figure({
        title: "First Graph",
        x_axis_label: "X-Axis",
        y_axis_label: "Y-Axis",
        width: 600,
        height: 400
    });

    plot1.vbar({x: { field: 'x' }, top: { field: 'y' }, source: source1, color: 'blue' });

    // Create the second graph
    const source2 = new Bokeh.ColumnDataSource({
        data: {
            x: [1, 2, 3, 4, 5],
            y: [4, 3, 2, 5, 6]
        }
    });

    const plot2 = new Bokeh.Plotting.figure({
        title: "Second Graph",
        x_axis_label: "X-Axis",
        y_axis_label: "Y-Axis",
        width: 600,
        height: 200
    });

    plot2.vbar({x: { field: 'x' }, top: { field: 'y' }, source: source2, line_width: 2, color: 'green' });

    // Render the plots
    const layout = new Bokeh.Column([plot1, plot2])
    Bokeh.Plotting.show(layout, document.getElementById("graph1"));
    //Bokeh.Plotting.show(plot1, document.getElementById("graph1"));
    //Bokeh.Plotting.show(plot2, document.getElementById("graph2")); 
</script>

</body>
</html>

A minimal example of the range_tool example working in BokehJS would be appreciated too, and thank you for reading my question!

I have not tried but I expect that you need to initialized Column with an object, e.g. more like

const layout = new Bokeh.Column({children: [plot1, plot2]})

Some of the Python model counterparts have “convenience” APIs for initializing, etc. but AFAIK everything on the BokehJS is initialized exactly the same way by passing an object with the property values to set.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.