I'm trying to create a skill tree using networkx, but due to the length of descriptions, it's not feasible to have permanent labels/annotations with the ability descriptions, so was hoping to be able to have them show up on mouseover.
The gist of the code is:
G = nx.Graph()
G.add_node('A', name='Node A', description='This is node A')
G.add_node('B', name='Node B', description='This is node B')
G.add_edge('A', 'B')
pos = nx.kamada_kawai_layout(G)
col_a='#000000'
col_b='#111111'
colours={'A':col_a, 'B':col_b}
fig, ax = plt.subplots(figsize=(20, 20))
nx.draw(G, pos, node_color=[colors[node] for node in G.nodes()], with_labels=False, node_size=2700)
node_labels = nx.get_node_attributes(G, 'name')
nx.draw_networkx_labels(G, pos, labels=node_labels, font_size=9)
ax.set_facecolor("#666666")
mpld3.save_html(fig,"Skill tree.html")
I don't know if it matters but I'm using JupyterLab through anaconda.
What I have tried:
I had someone provide the following code to try:
class NodeDescription(plugins.PluginBase):
JAVASCRIPT = """
mpld3.register_plugin("node_description", NodeDescription);
NodeDescription.prototype = Object.create(mpld3.Plugin.prototype);
NodeDescription.prototype.constructor = NodeDescription;
function NodeDescription(fig, props){
mpld3.Plugin.call(this, fig, props);
};
NodeDescription.prototype.draw = function(){
var tooltip = this.props.tooltip;
for (var i = 0; i < this.fig.axes.length; i++){
var ax = this.fig.axes[i];
ax.elements.push(mpld3.path_tooltip(tooltip));
}
}
"""
def __init__(self, points, tooltip, **kwargs):
self.points = points
self.tooltip = tooltip
self.metadata = kwargs
def get_dict(self):
x = [point[0] for point in self.points]
y = [point[1] for point in self.points]
return {'type': 'node_description', 'x': x, 'y': y, 'tooltip': self.tooltip, 'metadata': self.metadata}
def get_javascript(self):
return self.JAVASCRIPT
node_positions = [(x, y) for x, y in pos.values()]
node_descriptions = nx.get_node_attributes(G, 'description')
plugins.connect(fig, NodeDescription(node_positions, tooltip=list(node_descriptions.values())))
This didn't work, but I don't know if there is an error in it or if it just isn't right for what I want.