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!
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: