How to change the networkx graph by selection?

I just created enough plots and added them to the layout, in the js callback I just set visible the selected one and set invisible the others. For bigger data, it’s not a good solution. How to deal with it? (i used nx.DiGraph)
plots count is 437, and the data length is 4650

from bokeh.io import output_notebook
output_notebook()

import pandas as pd
import networkx as nx
from bokeh.io import output_notebook, show, output_file
from bokeh.layouts import column, row
from bokeh.models import (Plot, Range1d, Circle, HoverTool, TapTool, BoxSelectTool, ColumnDataSource,
                          LabelSet, CustomJS, Select, Legend, LegendItem, MultiLine, NodesAndLinkedEdges, StaticLayoutProvider)
from bokeh.plotting import figure, from_networkx
from bokeh.palettes import Blues4

import math

data = pd.read_csv('data.csv')
data['id'] = data['id'].astype(float).astype(str)
data['parentID'] = data['parentID'].astype(str)
data['firstName'] = data['firstName'].astype(str)
data['lastName'] = data['lastName'].astype(str)

data = data.sort_values(by = 'credit', ascending = False).reset_index(drop=True)

dd = set(data['id'])
dd.add('nan')

len(dd)

nones = data['parentID'][(data['parentID'].isin(dd) == False)].unique()

list_of_nans = []
for i in nones:
  l = [i, 0, '', 0, '', '', 0.0, 0]
  list_of_nans.append(l)

ll = pd.DataFrame(list_of_nans, columns = data.columns)
data = pd.concat([ll, data], ignore_index=False)

second_followers_filtered = data[(data['secondLevelfollowersCount'] > 0)].sort_values(by = 'firstName').reset_index(drop=True)
names_second = second_followers_filtered['firstName'] + ' ' + second_followers_filtered['lastName']
second_people = pd.DataFrame({'id': second_followers_filtered['id'], 'name': names_second})

colors = ["#d7191c", "#fdae61", "#a6d96a", "#1a9641"]

def set_coords(DG, parent_id, angle, radius, i):
    parent_coord = DG.nodes[parent_id]['pos']
    x = parent_coord[0] + radius * math.cos(angle * i)
    y = parent_coord[1] + radius * math.sin(angle * i)
    return (x, y)

def set_second_level_coords(DG, parent_id, num_followers, angle):
    parent_coord = DG.nodes[parent_id]['pos']
    parent_angle = math.atan2(parent_coord[1], parent_coord[0])
    sector_angle = angle * math.pi / 180
    angle_increment = sector_angle / num_followers if num_followers > 1 else 0
    if num_followers % 2 != 0:
        angle_start = (parent_angle - sector_angle / 2) + (sector_angle / 2)
    else:
        angle_start = (parent_angle - sector_angle / 2) + (sector_angle / 2) + (angle_increment / 2)
    coords = []
    angle = 0
    for i in range(num_followers):
        angle = angle_start - angle_increment * (num_followers // 2 - i) if num_followers > 1 else angle_start
        x = parent_coord[0] + 0.45 * math.cos(angle)
        y = parent_coord[1] + 0.45 * math.sin(angle)
        coords.append((x, y))
    return coords
    return coords

def di_graph(central_node):
    DG = nx.DiGraph()

    parent_id = data['parentID'][data['id'] == central_node].values[0]
    parent_name = data['firstName'][data['id'] == parent_id].values[0] if data['parentID'][data['id'] == central_node].values[0] != 'nan' else "None"
    firstF = data['followersCount'][data['id'] == central_node].values[0]
    secondF = data['secondLevelfollowersCount'][data['id'] == central_node].values[0]

    DG.add_node(central_node, label=data['firstName'][data['id'] == central_node].values[0],
                ardx=data['credit'][data['id'] == central_node].values[0],
                parent_info = parent_name, first = firstF, second = secondF, pos=(0, 0))

    first_level = data[data['parentID'] == central_node]
    alpha = 2 * math.pi / len(first_level) if len(first_level) > 1 else 0
    for i, row in enumerate(first_level.iterrows()):
        node_id = row[1]['id']
        coord = set_coords(DG, central_node, alpha, 0.5, i)
        parent_name = data['firstName'][data['id'] == row[1]['parentID']].values[0]
        firstF = row[1]['followersCount']
        secondF = row[1]['secondLevelfollowersCount']
        DG.add_node(node_id, label=row[1]['firstName'], ardx=row[1]['credit'],
                    parent_info = parent_name, first = firstF, second = secondF, pos=coord)
        DG.add_edge(central_node, node_id)
        DG.add_edge(node_id, central_node)

    for parent_id in first_level['id']:
        second_level = data[data['parentID'] == parent_id]
        coords = set_second_level_coords(DG, parent_id, len(second_level), 720/len(first_level))
        for i, row in enumerate(second_level.iterrows()):
            node_id = row[1]['id']
            coord = coords[i]
            parent_name = data['firstName'][data['id'] == row[1]['parentID']].values[0]
            firstF = row[1]['followersCount']
            secondF = row[1]['secondLevelfollowersCount']
            DG.add_node(node_id, label=row[1]['firstName'], ardx=row[1]['credit'],
                        parent_info = parent_name, first = firstF, second = secondF, pos=coord)
            DG.add_edge(parent_id, node_id)
            DG.add_edge(node_id, parent_id)

    node_colors = []
    for node in DG.nodes():
        if node in data['id'][data['credit'] < 500].values:
            node_colors.append(colors[0])
        elif node in data['id'][(data['credit'] >= 500) & (data['currentArdx'] < 1000)].values:
            node_colors.append(colors[1])
        elif node in data['id'][(data['credit'] >= 1000) & (data['currentArdx'] < 2500)].values:
            node_colors.append(colors[2])
        else:
            node_colors.append(colors[3])

    node_sizes = []
    node_line_colors = []
    for node in DG.nodes():
        if node == central_node:
            node_sizes.append(55)
            node_line_colors.append('black')
        elif node in first_level['id'].values:
            node_sizes.append(35)
            node_line_colors.append('#555555')
        else:
            node_sizes.append(20)
            node_line_colors.append('#a9a9a9')

    labels = [DG.nodes[node]['label'] if (node == central_node or node in first_level['id'].values) else '' for node in DG.nodes()]

    return DG, node_colors, node_sizes, node_line_colors, labels

def create_network_plot(data, central_node):
    DG, node_colors, node_sizes, node_line_colors, labels = di_graph(central_node)
    node_mapping = {node: i for i, node in enumerate(DG.nodes())}
    DG_int = nx.relabel_nodes(DG, node_mapping)
    pos = nx.get_node_attributes(DG_int, 'pos')

    network_graph = from_networkx(DG_int, layout_function=nx.spring_layout)
    network_graph.layout_provider = StaticLayoutProvider(graph_layout=pos)


    network_graph.node_renderer.data_source.data['colors'] = node_colors
    network_graph.node_renderer.data_source.data['sizes'] = node_sizes
    network_graph.node_renderer.data_source.data['line_colors'] = node_line_colors
    network_graph.node_renderer.glyph = Circle(size='sizes', fill_color='colors', line_color='line_colors', line_width = 2)
    network_graph.edge_renderer.glyph = MultiLine(line_color="grey", line_alpha=0.8, line_width=3)

    network_graph.node_renderer.data_source.data['firstName'] = [DG.nodes[node]['label'] for node in DG.nodes()]
    network_graph.node_renderer.data_source.data['credit'] = [DG.nodes[node]['ardx'] for node in DG.nodes()]

    network_graph.node_renderer.hover_glyph = Circle(size=0.8, fill_color="white", line_width=3, line_color='black')
    network_graph.node_renderer.selection_glyph = Circle(size=0.8, fill_color="white", line_width=3, line_color='black')

    network_graph.edge_renderer.glyph = MultiLine(line_alpha=0.5, line_width=1)
    network_graph.edge_renderer.selection_glyph = MultiLine(line_color="black", line_width=3)
    network_graph.edge_renderer.hover_glyph = MultiLine(line_color="black", line_width=3)

    network_graph.selection_policy = NodesAndLinkedEdges()
    network_graph.inspection_policy = NodesAndLinkedEdges()

    plot = figure(title="Network of Relations", x_range=Range1d(-1.5, 1.5), y_range=Range1d(-1.5, 1.5),
                  tools="pan,wheel_zoom,save,reset", active_scroll='wheel_zoom', width=800, height=600)
    plot.title.text_font_size = "16px"
    hover_tool = HoverTool(tooltips=[("First name", "@firstName"), ("Current Ardx", "@credit"),
                  ("Parent name", "@parent_info"), ("1st level followers", "@first"), ("2nd level followers", "@second")])
    plot.add_tools(hover_tool, TapTool(), BoxSelectTool())

    plot.renderers.append(network_graph)

    x, y = zip(*network_graph.layout_provider.graph_layout.values())
    source = ColumnDataSource({'x': x, 'y': y, 'firstName': labels})
    labels = LabelSet(x='x', y='y', text='firstName', source=source, text_align='center', text_baseline='middle',
                      text_font_size='10pt', text_color='black')
    plot.add_layout(labels)

    items = [
        LegendItem(label=f"Ardx < 500", renderers=[plot.circle(x=100, y=100, size=15, fill_color=colors[0])]),
        LegendItem(label=f"500 =< Ardx < 1000", renderers=[plot.circle(x=100, y=100, size=15, fill_color=colors[1])]),
        LegendItem(label=f"1000 =< Ardx < 2500", renderers=[plot.circle(x=100, y=100, size=15, fill_color=colors[2])]),
        LegendItem(label=f"2500 =< Ardx", renderers=[plot.circle(x=100, y=100, size=15, fill_color=colors[3])])
    ]
    legends = Legend(items=items, )
    plot.add_layout(legends)
    plot.legend.title = "Current Ardx"
    plot.legend.title_text_font_style = "bold"
    plot.legend.title_text_font_size = "16px"
    plot.legend.label_text_font_size = "12px"

    plot.axis.visible = False

    return plot

def selection(tit, datafr, plts):
    initial_value = datafr.name.iloc[0] if not datafr.empty else '' 
    select = Select(title= tit, value=initial_value,
                     options=datafr.name.tolist(), width=300)
    return select

code_ = """
        var selected = select.value;
        var main_p_ids = ids;
        var main_p_names = names;

        for (var key in plots) {
            plots[key].visible = false;
        }

        for (var i = 0; i < main_p_names.length; i++) {
            if (main_p_names[i] == selected) {
                plots[main_p_ids[i]].visible = true;
                break;
            }
        }
    """

nodes_of_second = second_people['id'].tolist()

def children_plots(chs):
    plots = {}
    for node in chs:
        plots[node] = create_network_plot(data, node)
    layout = column(*[plot for plot in plots.values()])
    for plot in plots.values():
        plot.visible = False
    if chs:
        plots[chs[0]].visible = True
    names_second = data['firstName'][data['id'].isin(chs)] + ' ' + data['lastName'][data['id'].isin(chs)] 
    people = pd.DataFrame({'id': chs, 'name': names_second})
    sel = selection('Select person with 1st level followers', people, plots)
    callback = CustomJS(args=dict(plots=plots, select=sel, ids = people['id'].tolist(), 
                                  names = people['name'].tolist()), code=code_)
    sel.js_on_change('value', callback)
    first_layout = column([sel, layout], margin=(0, 0, 0, 10))
    return first_layout

plots_of_second = {}
childrens = []
layouts_of_children = {}
lays = {}
for node in nodes_of_second:
    plots_of_second[node] = create_network_plot(data, node)
    childrens = data['id'][data['parentID'] == node].tolist()
    layouts_of_children[node] = children_plots(childrens)
    lays[node] = row([plots_of_second[node], layouts_of_children[node]])

sel2 = selection('Select person with 2nd level followers', second_people, plots_of_second)
callback2 = CustomJS(args=dict(plots=plots_of_second, select=sel2, ids = second_people['id'][:10].tolist(), names = second_people['name'][:10].tolist()), code=code_)
sel2.js_on_change('value', callback2)

layout = column(*[plot for plot in lays.values()])
for plot in lays.values():
    plot.visible = False
if nodes_of_second:
    lays[nodes_of_second[0]].visible = True


second_layout = column([sel2, layout] , margin=(0, 0, 0, 20))

show(second_layout)

Hi @Enkhzul_Byambasuren you have not provided enough information to be able to assist. How many plots? How much data? Most importantly, what is really needed is a complete Minimal Reproducible Example that can be investigated directly.

Sorry, I edited my post

@Enkhzul_Byambasuren That example is not complete, it is not runnable without a data file that you have not provided:

FileNotFoundError: [Errno 2] No such file or directory: 'data.csv'

I would need some representative file (e.g. with fake data if necessary) or else the script would need to generate synthetic data sufficient to demonstrate the issue. You also have not stated what version of Bokeh you are using, which is critical information.

Otherwise, all I can state is that 437 plots is actually quite alot for one page, as plots are fairly heavyweight objects. If I am understanding correctly you are sending so many plots in order to make one single one of them visible at a time, in response to some other selection? Layout re-computation is also an expensive operation and you are probably triggering hundreds of them in a row. Without any other information I would already suggest that this is not a viable approach.

I would suggest making only a single plot, with 437 gylphs added to it, and to toggle the visibility of the glyphs, instead.

I changed the records of my data. I hope it will work. Also I’m using bokeh 3.5.0

from bokeh.io import output_notebook
output_notebook()

import pandas as pd
import networkx as nx
from bokeh.io import output_notebook, show, output_file
from bokeh.layouts import column, row
from bokeh.models import (Plot, Range1d, Circle, HoverTool, TapTool, BoxSelectTool, ColumnDataSource,
                          LabelSet, CustomJS, Select, Legend, LegendItem, MultiLine, NodesAndLinkedEdges, StaticLayoutProvider)
from bokeh.plotting import figure, from_networkx
from bokeh.palettes import Blues4

import math

data = pd.read_csv('final.csv')
data['id'] = data['id'].astype(float).astype(str)
data['parentID'] = data['parentID'].astype(str)
data['firstName'] = data['firstName'].astype(str)
data['lastName'] = data['lastName'].astype(str)

data = data.sort_values(by = 'credit', ascending = False).reset_index(drop=True)

dd = set(data['id'])
dd.add('nan')

len(dd)

nones = data['parentID'][(data['parentID'].isin(dd) == False)].unique()

list_of_nans = []
for i in nones:
  l = [i, 0, '', 0, '', '', 0.0, 0]
  list_of_nans.append(l)

ll = pd.DataFrame(list_of_nans, columns = data.columns)
data = pd.concat([ll, data], ignore_index=False)

second_followers_filtered = data[(data['secondLevelfollowersCount'] > 0) & (data['credit'] > 2000)].sort_values(by = 'firstName').reset_index(drop=True)
names_second = second_followers_filtered['firstName'] + ' ' + second_followers_filtered['lastName']
second_people = pd.DataFrame({'id': second_followers_filtered['id'], 'name': names_second})

colors = ["#d7191c", "#fdae61", "#a6d96a", "#1a9641"]

def set_coords(DG, parent_id, angle, radius, i):
    parent_coord = DG.nodes[parent_id]['pos']
    x = parent_coord[0] + radius * math.cos(angle * i)
    y = parent_coord[1] + radius * math.sin(angle * i)
    return (x, y)

def set_second_level_coords(DG, parent_id, num_followers, angle):
    parent_coord = DG.nodes[parent_id]['pos']
    parent_angle = math.atan2(parent_coord[1], parent_coord[0])
    sector_angle = angle * math.pi / 180
    angle_increment = sector_angle / num_followers if num_followers > 1 else 0
    if num_followers % 2 != 0:
        angle_start = (parent_angle - sector_angle / 2) + (sector_angle / 2)
    else:
        angle_start = (parent_angle - sector_angle / 2) + (sector_angle / 2) + (angle_increment / 2)
    coords = []
    angle = 0
    for i in range(num_followers):
        angle = angle_start - angle_increment * (num_followers // 2 - i) if num_followers > 1 else angle_start
        x = parent_coord[0] + 0.45 * math.cos(angle)
        y = parent_coord[1] + 0.45 * math.sin(angle)
        coords.append((x, y))
    return coords
    return coords

def di_graph(central_node):
    DG = nx.DiGraph()

    parent_id = data['parentID'][data['id'] == central_node].values[0]
    parent_name = data['firstName'][data['id'] == parent_id].values[0] if data['parentID'][data['id'] == central_node].values[0] != 'nan' else "None"
    firstF = data['followersCount'][data['id'] == central_node].values[0]
    secondF = data['secondLevelfollowersCount'][data['id'] == central_node].values[0]

    DG.add_node(central_node, label=data['firstName'][data['id'] == central_node].values[0],
                ardx=data['credit'][data['id'] == central_node].values[0],
                parent_info = parent_name, first = firstF, second = secondF, pos=(0, 0))

    first_level = data[data['parentID'] == central_node]
    alpha = 2 * math.pi / len(first_level) if len(first_level) > 1 else 0
    for i, row in enumerate(first_level.iterrows()):
        node_id = row[1]['id']
        coord = set_coords(DG, central_node, alpha, 0.5, i)
        parent_name = data['firstName'][data['id'] == row[1]['parentID']].values[0]
        firstF = row[1]['followersCount']
        secondF = row[1]['secondLevelfollowersCount']
        DG.add_node(node_id, label=row[1]['firstName'], ardx=row[1]['credit'],
                    parent_info = parent_name, first = firstF, second = secondF, pos=coord)
        DG.add_edge(central_node, node_id)
        DG.add_edge(node_id, central_node)

    for parent_id in first_level['id']:
        second_level = data[data['parentID'] == parent_id]
        coords = set_second_level_coords(DG, parent_id, len(second_level), 720/len(first_level))
        for i, row in enumerate(second_level.iterrows()):
            node_id = row[1]['id']
            coord = coords[i]
            parent_name = data['firstName'][data['id'] == row[1]['parentID']].values[0]
            firstF = row[1]['followersCount']
            secondF = row[1]['secondLevelfollowersCount']
            DG.add_node(node_id, label=row[1]['firstName'], ardx=row[1]['credit'],
                        parent_info = parent_name, first = firstF, second = secondF, pos=coord)
            DG.add_edge(parent_id, node_id)
            DG.add_edge(node_id, parent_id)

    node_colors = []
    for node in DG.nodes():
        if node in data['id'][data['credit'] < 500].values:
            node_colors.append(colors[0])
        elif node in data['id'][(data['credit'] >= 500) & (data['credit'] < 1000)].values:
            node_colors.append(colors[1])
        elif node in data['id'][(data['credit'] >= 1000) & (data['credit'] < 2500)].values:
            node_colors.append(colors[2])
        else:
            node_colors.append(colors[3])

    node_sizes = []
    node_line_colors = []
    for node in DG.nodes():
        if node == central_node:
            node_sizes.append(55)
            node_line_colors.append('black')
        elif node in first_level['id'].values:
            node_sizes.append(35)
            node_line_colors.append('#555555')
        else:
            node_sizes.append(20)
            node_line_colors.append('#a9a9a9')

    labels = [DG.nodes[node]['label'] if (node == central_node or node in first_level['id'].values) else '' for node in DG.nodes()]

    return DG, node_colors, node_sizes, node_line_colors, labels

def create_network_plot(data, central_node):
    DG, node_colors, node_sizes, node_line_colors, labels = di_graph(central_node)
    node_mapping = {node: i for i, node in enumerate(DG.nodes())}
    DG_int = nx.relabel_nodes(DG, node_mapping)
    pos = nx.get_node_attributes(DG_int, 'pos')

    network_graph = from_networkx(DG_int, layout_function=nx.spring_layout)
    network_graph.layout_provider = StaticLayoutProvider(graph_layout=pos)


    network_graph.node_renderer.data_source.data['colors'] = node_colors
    network_graph.node_renderer.data_source.data['sizes'] = node_sizes
    network_graph.node_renderer.data_source.data['line_colors'] = node_line_colors
    network_graph.node_renderer.glyph = Circle(size='sizes', fill_color='colors', line_color='line_colors', line_width = 2)
    network_graph.edge_renderer.glyph = MultiLine(line_color="grey", line_alpha=0.8, line_width=3)

    network_graph.node_renderer.data_source.data['firstName'] = [DG.nodes[node]['label'] for node in DG.nodes()]
    network_graph.node_renderer.data_source.data['credit'] = [DG.nodes[node]['ardx'] for node in DG.nodes()]

    network_graph.node_renderer.hover_glyph = Circle(size=0.8, fill_color="white", line_width=3, line_color='black')
    network_graph.node_renderer.selection_glyph = Circle(size=0.8, fill_color="white", line_width=3, line_color='black')

    network_graph.edge_renderer.glyph = MultiLine(line_alpha=0.5, line_width=1)
    network_graph.edge_renderer.selection_glyph = MultiLine(line_color="black", line_width=3)
    network_graph.edge_renderer.hover_glyph = MultiLine(line_color="black", line_width=3)

    network_graph.selection_policy = NodesAndLinkedEdges()
    network_graph.inspection_policy = NodesAndLinkedEdges()

    plot = figure(title="Network of Relations", x_range=Range1d(-1.5, 1.5), y_range=Range1d(-1.5, 1.5),
                  tools="pan,wheel_zoom,save,reset", active_scroll='wheel_zoom', width=800, height=600)
    plot.title.text_font_size = "16px"
    hover_tool = HoverTool(tooltips=[("First name", "@firstName"), ("Current Ardx", "@credit"),
                  ("Parent name", "@parent_info"), ("1st level followers", "@first"), ("2nd level followers", "@second")])
    plot.add_tools(hover_tool, TapTool(), BoxSelectTool())

    plot.renderers.append(network_graph)

    x, y = zip(*network_graph.layout_provider.graph_layout.values())
    source = ColumnDataSource({'x': x, 'y': y, 'firstName': labels})
    labels = LabelSet(x='x', y='y', text='firstName', source=source, text_align='center', text_baseline='middle',
                      text_font_size='10pt', text_color='black')
    plot.add_layout(labels)

    items = [
        LegendItem(label=f"Ardx < 500", renderers=[plot.circle(x=100, y=100, size=15, fill_color=colors[0])]),
        LegendItem(label=f"500 =< Ardx < 1000", renderers=[plot.circle(x=100, y=100, size=15, fill_color=colors[1])]),
        LegendItem(label=f"1000 =< Ardx < 2500", renderers=[plot.circle(x=100, y=100, size=15, fill_color=colors[2])]),
        LegendItem(label=f"2500 =< Ardx", renderers=[plot.circle(x=100, y=100, size=15, fill_color=colors[3])])
    ]
    legends = Legend(items=items, )
    plot.add_layout(legends)
    plot.legend.title = "Current Ardx"
    plot.legend.title_text_font_style = "bold"
    plot.legend.title_text_font_size = "16px"
    plot.legend.label_text_font_size = "12px"

    plot.axis.visible = False

    return plot

def selection(tit, datafr, plts):
    initial_value = datafr.name.iloc[0] if not datafr.empty else '' 
    select = Select(title= tit, value=initial_value,
                     options=datafr.name.tolist(), width=300)
    return select

code_ = """
        var selected = select.value;
        var main_p_ids = ids;
        var main_p_names = names;

        for (var key in plots) {
            plots[key].visible = false;
        }

        for (var i = 0; i < main_p_names.length; i++) {
            if (main_p_names[i] == selected) {
                plots[main_p_ids[i]].visible = true;
                break;
            }
        }
    """

nodes_of_second = second_people['id'].tolist()

def children_plots(chs):
    plots = {}
    for node in chs:
        plots[node] = create_network_plot(data, node)
    layout = column(*[plot for plot in plots.values()])
    for plot in plots.values():
        plot.visible = False
    if chs:
        plots[chs[0]].visible = True
    names_second = data['firstName'][data['id'].isin(chs)] + ' ' + data['lastName'][data['id'].isin(chs)] 
    people = pd.DataFrame({'id': chs, 'name': names_second})
    sel = selection('Select person with 1st level followers', people, plots)
    callback = CustomJS(args=dict(plots=plots, select=sel, ids = people['id'].tolist(), 
                                  names = people['name'].tolist()), code=code_)
    sel.js_on_change('value', callback)
    first_layout = column([sel, layout], margin=(0, 0, 0, 10))
    return first_layout

plots_of_second = {}
childrens = []
layouts_of_children = {}
lays = {}
for node in nodes_of_second:
    plots_of_second[node] = create_network_plot(data, node)
    childrens = data['id'][data['parentID'] == node].tolist()
    layouts_of_children[node] = children_plots(childrens)
    lays[node] = row([plots_of_second[node], layouts_of_children[node]])

sel2 = selection('Select person with 2nd level followers', second_people, plots_of_second)
callback2 = CustomJS(args=dict(plots=plots_of_second, select=sel2, ids = second_people['id'][:10].tolist(), names = second_people['name'][:10].tolist()), code=code_)
sel2.js_on_change('value', callback2)

layout = column(*[plot for plot in lays.values()])
for plot in lays.values():
    plot.visible = False
if nodes_of_second:
    lays[nodes_of_second[0]].visible = True


second_layout = column([sel2, layout] , margin=(0, 0, 0, 20))

show(second_layout)

Sorry, Is it not possible to upload csv file?

I’m not aware that Discourse provides generic uploads. I usually use gists for this sort of thing: https://gist.github.com/

I uploaded the data here. If you look through my problem, I will greatly appreciate. Thank you

Trying to open the notebook:

Unreadable Notebook: /Users/bryan/Downloads/2208a4e0fd670aac4140afdcc8516c00-c398c1cb693d043b242ce47f1add17d7364d6c67/code.ipynb NotJSONError(“Notebook does not appear to be JSON: 'from bokeh.io import output_notebook\no…”)

Is the code in the notebook the same as the earlier code above? It’s actually much simpler and more preferable to have the code as a plain script, rather than a notebook.

Edit: I guess code.ipynb is actually a plain script, despite having an .ipynb notebook file suffix…

However, there is still a missing CSV when I run the code:

FileNotFoundError: [Errno 2] No such file or directory: 'final.csv'

There is a "lists.csv" from the download, but I am not going to spend more time trying to debug things that are not the actual problem at hand.

@Enkhzul_Byambasuren as I stated earlier, I don’t think sending hundreds of individual plots is a good strategy with Bokeh, in case that is what this code is doing. I think you should try to rework things to have a single plot, with many glyphs instead.

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