Color network graph node lines on click in Bokeh, Python

故事扮演 提交于 2021-02-10 14:21:55

问题


Using the following code with Bokeh server, I am currently able to color a selected node in my network graph pink by selecting it from a dropdown.

What I'd like to do is extend the code to do is allow me to perform the same highlight callback, when a node is clicked, using Taptool() or some other method. Is this possible?

import networkx as nx
from bokeh.models.graphs import from_networkx
from bokeh.models import Range1d, MultiLine, Circle, TapTool, Plot
from bokeh.plotting import figure
from bokeh.io import curdoc
from bokeh.layouts import row
from bokeh.models.widgets import Dropdown


def choose_node_outline_colors(node_clicked):
    outline_colors = []
    for node in G.nodes():
        if str(node) == node_clicked:
            outline_colors.append('pink')
        else:
            outline_colors.append('black')
    return outline_colors

def update_node_highlight(attrname, old, new):
    node_clicked = dropdown.value
    data['line_color'] = choose_node_outline_colors(node_clicked)

G = nx.karate_club_graph()

plot = Plot(plot_width=400, plot_height=400,
            x_range=Range1d(-1.1,1.1), y_range=Range1d(-1.1,1.1))
graph = from_networkx(
    G,
    nx.circular_layout,
    scale=1,
    center=(0,0)
)

# Create nodes and edges
data = graph.node_renderer.data_source.data
data['line_color'] = choose_node_outline_colors('1')
graph.node_renderer.glyph = Circle(size=10, line_color="line_color")
graph.edge_renderer.glyph = MultiLine(line_alpha=1.6, line_width=0.5)

# Add tap tool
plot.add_tools(TapTool())

plot.renderers.append(graph)

# Dropdown menu to highlight a particular node
dropdown = Dropdown(label="Highlight Node", menu=list(map(str, list(G.nodes()))))
dropdown.on_change('value', update_node_highlight)
dropdown.value = '1'

curdoc().add_root(row(plot, dropdown))


回答1:


Ok, I managed to find a solution using TapTool and making use of the node index:

import networkx as nx
from bokeh.models.graphs import from_networkx
from bokeh.models import Range1d, MultiLine, Circle, TapTool, Plot, HoverTool, BoxSelectTool
from bokeh.plotting import figure
from bokeh.io import curdoc
from bokeh.layouts import row
from bokeh.models.widgets import Dropdown
from bokeh.events import Tap


def choose_node_outline_colors(nodes_clicked):
    outline_colors = []
    for node in G.nodes():
        if str(node) in nodes_clicked:
            outline_colors.append('pink')
        else:
            outline_colors.append('black')
    return outline_colors


def update_node_highlight(event):
    nodes_clicked_ints = source.selected.indices
    nodes_clicked = list(map(str, nodes_clicked_ints))
    source.data['line_color'] = choose_node_outline_colors(nodes_clicked)


G = nx.karate_club_graph()

plot = Plot(plot_width=400, plot_height=400,
            x_range=Range1d(-1.1,1.1), y_range=Range1d(-1.1,1.1))
graph = from_networkx(
    G,
    nx.circular_layout,
    scale=1,
    center=(0,0)
)

# Create nodes and edges
source = graph.node_renderer.data_source
source.data['line_color'] = choose_node_outline_colors('1')
graph.node_renderer.glyph = Circle(size=10, line_color="line_color")
graph.edge_renderer.glyph = MultiLine(line_alpha=1.6, line_width=0.5)

# Add tap tool
TOOLTIPS = [
    ("Index", "@index"),
]
plot.add_tools(HoverTool(tooltips=TOOLTIPS), TapTool(), BoxSelectTool())

plot.renderers.append(graph)

taptool = plot.select(type=TapTool)

plot.on_event(Tap, update_node_highlight)

curdoc().add_root(plot)


来源:https://stackoverflow.com/questions/58430994/color-network-graph-node-lines-on-click-in-bokeh-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!