[1]:
%load_ext autoreload
%autoreload 2

Tutorial

A hands-on tutorial is always better than just scanning API documentations (especially for a visualization library). We will therefore explain the workings of this package on some examples.

[2]:
import networkx as nx
from bokehgraph import BokehGraph

A simple unipartite graph

The simplest example is probably the well known karate club graph.

A (almost) minimal working example is this. We use, however, an optional line for plot.layout(seed=42), just to make the documentation reproducible. If you want, you can safely omit this line but will get a different layout everytime.

The default layout for unipartite graphs is nx.spring_layout.

[3]:
g = nx.karate_club_graph()

plot = BokehGraph(g, hover_edges=True)
plot.layout(seed=42)
fig = plot.draw(return_figure=False)

A simple bipartite graph

NetworkX has not built-in subclass for bipartite networks. We can therefore not automatically detect whether or not a network is actually bipartite or not. To enable a bipartite visualization of a network, we can simply set bipartite=1 during the initialization of the BokehGraph object. Make sure that all nodes have the bipartite attribute actually set to either 0 or 1 or you will encounter errors moving forward.

[4]:
g = nx.Graph()
g.add_node(1, bipartite=0)
g.add_node(2, bipartite=0)
g.add_node(3, bipartite=1, gender="m")
g.add_node(4, bipartite=1, gender="w")
g.add_edge(1, 3)
g.add_edge(1, 4)
g.add_edge(2, 3)
g.add_edge(2, 4)

plot = BokehGraph(
    g,
    hover_edges=True,
    bipartite=True,
)
plot.layout(seed=42)
plot.draw(node_size=19)

Setting parameters in BokehGraph.draw

To set parameters to modify the visualization, all parameters starting with node_ can be set to either 1 or 2 values. The purpose is to allow parameters to be set separately for level 0 and level 1 of bipartite graphs. Since edges are not split into multiple levels, this

If only on parameter is set in a bipartite graph, it will be used for both levels.

If 2 parameters are set for a unipartite graph, only the first parameter will be used and the latter one will be ignored.

Most parameters can be set to either a node/edge attribute or to a specific value. If it is set to a node/edge attribute the nodes/edges will be colored accordingly. In this example firebrick is not a node attribute but a predefined color of bokeh, so all nodes on level 0 have the same color but level 1 nodes are colored by the node attribute housing_type.

[5]:
g = nx.Graph()
g.add_node(1, bipartite=0, gender="female")
g.add_node(2, bipartite=0, gender="male")
g.add_node(3, bipartite=1, housing_type="castle")
g.add_node(4, bipartite=1, housing_type="house")
g.add_edge(1, 3)
g.add_edge(1, 4)
g.add_edge(2, 3)
g.add_edge(2, 4)

plot = BokehGraph(
    g,
    bipartite=True,
)
plot.layout(seed=42)
plot.draw(
    node_size=(19, 25),
    node_color=("firebrick", "housing_type"),
)

A more complex example to showcase some features

[6]:
g = nx.davis_southern_women_graph()

plot = BokehGraph(
    graph=g,
    width=700,
    height=800,
    inline=True,
    hover_edges=True,
    hover_nodes=True,
    bipartite=True,
)

betweenness = nx.bipartite.betweenness_centrality(
    g, nodes=(node for node, data in g.nodes(data=True) if data["bipartite"] == 1)
)
nx.set_node_attributes(g, betweenness, "betweenness")

layout = nx.spring_layout(g, seed=42)
plot.layout(layout)
plot.draw(
    node_marker=("hex", "inverted_triangle"),
    node_color=("betweenness", "steelblue"),
    node_palette="magma",
    node_max_colors=5,
    node_size=(25, 30),
    edge_alpha=0.4,
)