Networkx Graph and Scatter Plot link selection

I am trying to link three different plot using link selection. I was able to successfully link the scatter plots, but I could not figure out how to link the networkx graph. I have attached my code below and if anyone can provide some information, please let me know.

    def neo4j_to_dataframe(self, results):
        nodes = {}
        relationships = {}
        for result in results:
            n = result.get('n',None)

            if n is not None and n.element_id not in nodes:
                node_data = dict(n.items())
                element_id = n.element_id
                node_data['element_id'] = element_id
                nodes[element_id] = node_data

            m = result.get('m',None)
            if m is not None and m.element_id not in nodes:
                node_data = dict(m.items())
                element_id = m.element_id
                node_data['element_id'] = element_id
                nodes[element_id] = node_data

            r = result.get('r', None)
            print(r)
            if r is not None and r.element_id not in relationships:
                relationship_data = {}
                relationship_data['type'] = result['r'].type
                relationship_data['element_id'] = r.element_id
                relationship_data['start_node'] = r.nodes[0].element_id
                relationship_data['end_node'] = r.nodes[1].element_id
                relationships[r.element_id] = (relationship_data)
        nodes = list(nodes.values())
        relationships = list(relationships.values())

        nodes = pd.DataFrame(nodes)
        relationships = pd.DataFrame(relationships)
        return nodes, relationships

pos = graphviz_layout(graph, prog="twopi")
hv_graph = hv.Graph.from_networkx(graph, pos)
hv_graph.opts(opts.Graph(node_size=8,edge_line_width=1,node_fill_color='color', width=400,height=400,inspection_policy='nodes',title='Neo4j Graph Visualization',))

nodes_df.set_index("element_id", inplace=True)
relationship_df.set_index("element_id", inplace=True)

scatter_plot_1 = nodes_df.hvplot.points(x='columnA', y='columnB',  width=500)
scatter_plot_2 = nodes_df.hvplot.points(x='columnC', y='columnD', width=500)
ls = hv.link_selections.instance()
ls(scatter_plot_1 + scatter_plot_2 + hv_graph)

The two scatter plots are linked and I can select different points on the graph and I can see the related points, but the highlighting is not working with graph.

1 Like

Hi @super

Would it be possible to share a Minimal, Reproducible Example? That would make it much easier to understand the problem and try to find a solution. Thx.

Hello @Marc

import networkx as nx
import pandas as pd
import holoviews as hv
import hvplot.pandas
hv.extension('bokeh')

G = nx.DiGraph()

people = [
    {"name":"Alice", "id":1, "age":29, "occupation" : "Data Scientist", "friends":["Bob","Carol"]},
    {"name":"Bob",   "id":2, "age":25, "occupation" : "Engineer", "friends":["Alice","Dave"]},
    {"name":"Carol", "id":3, "age":24, "occupation" : "Doctor", "friends":["Alice","Eve"]},
    {"name":"Dave",  "id":4, "age":22, "occupation" : "Software Engineer", "friends":["Bob"]},
    {"name":"Eve",   "id":5, "age":30, "occupation" : "Lawyer", "friends":["Carol"]},
]

positions = [
    {"id":1, "position": "Senior"},
    {"id":2, "position": "Junior"},
    {"id":3, "position": "resident"},
    {"id":4, "position": "Staff"},
    {"id":5, "position": "partner"},
]

for person in people:
    G.add_node(person["name"], age=person["age"], occupation=person["occupation"] , id = person["id"])

for person in people:
    for friend in person["friends"]:
        G.add_edge(person["name"],friend)

hv_graph = hv.Graph.from_networkx(G,nx.spring_layout)


df_A = pd.DataFrame(people)
df_B = pd.DataFrame(positions)
plotA = df_A.hvplot.points(x='age', y='occupation',  width=500)
plotB = df_B.hvplot.points(x='id', y='position',  width=500)

ls = hv.link_selections.instance(index_cols=['id',])

ls(plotA + plotB +  hv_graph.nodes * hv_graph.edgepaths )

The above code works.If you selected a node you can see the linked data points. The problem with this approach is I am overlaying the edges over the nodes to draw the graph.

ls = hv.link_selections.instance(index_cols=['id',])

ls(plotA + plotB +  hv_graph)

I would like to link the graph directly without overlaying the edges.

Thank you in advance !