Jacob
Jacob

Reputation: 33

How can I add mouseover descriptions to nodes on a networkx diagram?

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 had some help in the comments that has since been deleted, the code that was given is below, but it doesn't provide the mouseover descriptions. So I'm just putting it here in case it's easily fixable and someone can help from it:

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())))

Upvotes: 3

Views: 787

Answers (1)

Dr. Prof. Patrick
Dr. Prof. Patrick

Reputation: 1374

I really encourage you to look into Bokeh. It's a python library that has a ton of options and does exactly what you need.

I wrote a very basic code to render the graph, but know that you can really make it your own and change the nodes' and edges' colors & size based on attributes.

First you need to install it:

pip install bokeh

And here's the code:

import networkx as nx

from bokeh.models import Circle
from bokeh.plotting import figure, output_file
from bokeh.plotting import from_networkx
from bokeh.io import save

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')

# there are multiple positioning algos, you should play around with them
pos = nx.kamada_kawai_layout(G)

HOVER_TOOLTIPS = [
            ("name", "@name"),
            ("description", "@description"),
        ]

# Create a plot — set dimensions, toolbar, and title
plot = figure(tooltips=HOVER_TOOLTIPS,
                tools="pan,wheel_zoom,save,reset", active_scroll='wheel_zoom', title='my plot', sizing_mode='stretch_both', width=1000, height=1000)

network_graph = from_networkx(G, nx.spring_layout, scale=10, center=(0, 0), pos=pos)
network_graph.node_renderer.glyph = Circle(size=50, fill_color='blue')

plot.renderers.append(network_graph)
output_file(filename=str('test.html'))
save(plot, filename='test.html')

And here some pictures of the result:

Without the mouse hover: enter image description here

Then when you hover with your mouse: enter image description here

Upvotes: 1

Related Questions