Search code examples
pythonnetworkxpyvis

Further editing for items in the PyVis Tooltip?


I'm doing a network visualization using PyVis and was hoping to add some additional items in the tooltip function when hovering on nodes.

I'm basically using the code straight from the tutorial section of the PyVis documentation for the GoT network: https://pyvis.readthedocs.io/en/latest/tutorial.html

The tooltip in this function is set-up so that it will show lists of adjacent neighbors when hovering on a node. I would like to display this same information, but would also like to display the associated edge weight for each neighbor.

I know that weight is being accounted for in my visualization since the edge width is changing depending on the weight, but the few attempts I've made haven't shown any change in the tooltip.

Here is what I've attempted in addition to the code responsible for the tooltip (Tooltip section is toward the bottom, just below the neighbor_map object):

HCP_net = Network(height='750px', width='100%', bgcolor='#222222', font_color='white')

HCP_net.barnes_hut()

sources = df2['HCP_Name']
targets = df2['HCPOffset_Name']
weights = df2['PATIENT_ID (DCOUNT)']

edge_data = zip(sources, targets, weights)

for e in edge_data:
    src = e[0]
    dst = e[1]
    w = e[2]
    
    HCP_net.add_node(src, src, title=src)
    HCP_net.add_node(dst, dst, title=dst)
    HCP_net.add_edge(src, dst, value=w)
    
neighbor_map = HCP_net.get_adj_list()
node_weight = HCP_net.get_edges() #my attempt at creating a weight object to call, if I call print(len(node_weight)) I get an integer so I know this is working

for node in HCP_net.nodes:
    node['title'] += ' Neighbors: <br>' + '<br>'.join(neighbor_map[node['id']])
    node['value'] = len(neighbor_map[node['id']])
    node['value'] = len(neighbor_map.keys()) #This called by itself 
 (print(len(neighbor_map.keys())) also displays the same integer as my node_weight object
    

I think I'm just not quite understanding how to correctly call the node['value'] to result in a new display in the tool tip. Any assistance is greatly appreciated!


Solution

  • The node['title'] variable stores the information being displayed while hovering the nodes. To add the weights to the information displayed, you first need to associate them to their corresponding neighbors and then change the node['title'] variable such that it contains the concatenated information neighbor and weight . You can find more details on how to do that in the code below:

    from pyvis.network import Network
    import pandas as pd
    
    got_net = Network(height='750px', width='100%', bgcolor='#222222', font_color='white')
    
    # set the physics layout of the network
    got_net.barnes_hut()
    got_data = pd.read_csv('https://www.macalester.edu/~abeverid/data/stormofswords.csv')
    
    sources = got_data['Source']
    targets = got_data['Target']
    weights = got_data['Weight']
    
    edge_data = zip(sources, targets, weights)
    
    for e in edge_data:
        src = e[0]
        dst = e[1]
        w = e[2]
    
        got_net.add_node(src, src, title=src)
        got_net.add_node(dst, dst, title=dst)
        got_net.add_edge(src, dst, value=w)
    
    neighbor_map = got_net.get_adj_list()
    edges = got_net.get_edges()
    nodes=got_net.get_nodes()
    
    N_nodes=len(nodes)
    N_edges=len(edges)
    
    
    weights=[[] for i in range(N_nodes)]
    
    #Associating weights to neighbors
    for i in range(N_nodes): #Loop through nodes
        for neighbor in neighbor_map[nodes[i]]: #and neighbors
            for j in range(N_edges): #associate weights to the edge between node and neighbor
                if (edges[j]['from']==nodes[i] and edges[j]['to']==neighbor) or \
                   (edges[j]['from']==neighbor and edges[j]['to']==nodes[i]):
                    weights[i].append(edges[j]['value'])
        
    
    for node,i in zip(got_net.nodes,range(N_nodes)):
       
        node['value']=len(neighbor_map[node['id']])
        node['weight']=[str(weights[i][k]) for k in range(len(weights[i]))]
        list_neighbor=list(neighbor_map[node['id']]) 
        #Concatenating neighbors and weights
        hover_str=[list_neighbor[k]+' '+ node['weight'][k] for k in range(node['value'])]
        #Setting up node title for hovering 
        node['title']+=' Neighbors:<br>'+'<br>'.join(hover_str)
        
    got_net.show('gameofthrones.html')
    

    And the output gives:

    enter image description here