0

I would like to update a network graph using a datetime range slider with Bokeh. So appearing/disappearing nodes depending on the datetime range, and also width of edges is proportional to the number of connections between sources and target within datetime range.

So far here is my code:

nb_conn = df.groupby(['src','dst'])['src'].count() nb_conn = nb_conn.rename("nb_conn") nb_conn_tot = nb_conn.sum() ratio_nb_conn = (nb_conn/nb_conn_tot)*100 netflow_feat = ( df.merge(ratio_nb_conn, on=["src", 'dst']) ) G = nx.from_pandas_edgelist(netflow_feat, source='src', target='dst' ,edge_attr='nb_conn') degrees = dict(nx.degree(G)) nx.set_node_attributes(G, name='degree', values=degrees) number_to_adjust_by = 5 adjusted_node_size = dict([(node, degree+number_to_adjust_by) for node, degree in nx.degree(G)]) nx.set_node_attributes(G, name='adjusted_node_size', values=adjusted_node_size) number_to_adjust_by = 5 adjusted_node_size = dict([(node, degree+number_to_adjust_by) for node, degree in nx.degree(G)]) nx.set_node_attributes(G, name='adjusted_node_size', values=adjusted_node_size) #Choose attributes from G network to size and color by — setting manual size (e.g. 10) or color (e.g. 'skyblue') also allowed size_by_this_attribute = 'adjusted_node_size' color_by_this_attribute = 'adjusted_node_size' #Pick a color palette — Blues8, Reds8, Purples8, Oranges8, Viridis8 color_palette = Blues8 #Choose a title! title = 'Cibles Network' #Establish which categories will appear when hovering over each node HOVER_TOOLTIPS = [ ("IP", "@index"), ] #Create a plot — set dimensions, toolbar, and title plot = figure(tooltips = HOVER_TOOLTIPS, tools="pan,wheel_zoom,save,reset", active_scroll='wheel_zoom', x_range=Range1d(-20.1, 20.1), y_range=Range1d(-20.1, 20.1), title=title) #Create a network graph object # https://networkx.github.io/documentation/networkx-1.9/reference/generated/networkx.drawing.layout.spring_layout.html\ network_graph = from_networkx(G, nx.spring_layout, scale=20, center=(0, 0)) #Set node sizes and colors according to node degree (color as spectrum of color palette) minimum_value_color = min(network_graph.node_renderer.data_source.data[color_by_this_attribute]) maximum_value_color = max(network_graph.node_renderer.data_source.data[color_by_this_attribute]) network_graph.node_renderer.glyph = Circle(fill_color=linear_cmap(color_by_this_attribute, color_palette, minimum_value_color, maximum_value_color)) #Set edge opacity and width network_graph.edge_renderer.data_source.data["line_width"] = [G.get_edge_data(a,b)['nb_conn'] for a, b in G.edges()] network_graph.edge_renderer.glyph = MultiLine(line_alpha=0.5) network_graph.edge_renderer.glyph.line_width = {'field': 'line_width'} plot.renderers.append(network_graph) backup_edge_data = copy.deepcopy(network_graph.edge_renderer.data_source.data) code = """ # print out array of date from, date to console.log(cb_obj.value); # dates returned from slider are not at round intervals and include time; const date_from = Date.parse(new Date(cb_obj.value[0]).toDateString()); const date_to = Date.parse(new Date(cb_obj.value[1]).toDateString()); const old_Weight = df["nb_conn"]; const old_start = df.loc[start]; const old_end = df.loc[end]; const df_filtered = df[(df['timestamp'] >= date_from) & (df['timestamp'] <= date_to)] What should I do here??? graph_setup.edge_renderer.data_source.data = new_data_edge; graph_setup.edge_renderer.data_source.change.emit(); """ callback = CustomJS(args = dict(graph_setup = network_graph, df=netflow_feat, start = netflow_feat['timestamp'].min, end = netflow_feat['timestamp'].max), code = code) datetime_range_slider = DatetimeRangeSlider(value=(datetime(2023, 1, 5, 12), datetime(2022, 1, 6, 18)), start=datetime(2023, 1, 5), end=datetime(2023, 1, 7)) datetime_range_slider.js_on_change("value", callback) layout = Column(plot, datetime_range_slider) show(layout) 

In the callback function, is it supposed to be only javascript? I guess my callback function is not correct but I don't know how to do what I'd like to do, or is it even possible?

2
  • Not sure about the whole Bokeh code but if you need to filter an array in javascript using your date_from and date_to you should use something like this const df_filtered = df.filter(edge => edge.timestamp >= date_from && edge.timestamp <= date_to); Commented Feb 17, 2023 at 11:45
  • @wayglem ok thanks, but then how do I update the graph with the df_filtered? Thanks Commented Feb 21, 2023 at 9:58

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.