In [1]:
import numpy as np
from bqplot import *
from bqplot.marks import Graph
from ipywidgets import Layout

Nodes and Links should be supplied to the Graph mark.

Node attributes

Attribute Type Description Default
label str node label mandatory attribute
label_display {center, outside, none} label display options center
shape {circle, ellipse, rect} node shape circle
shape_attrs dict node SVG attributes {'r': 15}

Link Attributes

Attribute Type Description Default
source int source node index mandatory attribute
target int target node index mandatory attribute
value float value of the link. Use np.nan if you do not want a link -

Link data can also be supplied using a link_matrix which is a numpy array of shape (n, n) where n is the number of nodes in the graph

Link Data can be passed in through 3 data attributes -

  1. link_data - list of dicts (e.g. [{'source': 0, 'target': 1, 'value': 10}, {'source': 2, 'target': 1, 'value': 20},...]
  2. link_matrix - 2-d numpy array of shape (n, n) where n is the number of nodes
  3. link_color - 2-d numpy array of shape (n, n) where n is the number of nodes. This attribute can be used to encode the link_color by passing in a link_color scale


In [2]:
fig_layout = Layout(width='960px', height='500px')

Directed Graph

If we dont specify the x and y location for nodes then the force layout will set the location of nodes


In [3]:
node_data = list('ABCDEFG')
link_data = [{'source': s, 'target': t} for s, t in np.random.randint(0, 7, (10, 2))]
graph = Graph(node_data=node_data, link_data=link_data, charge=-600, colors=['orange'] * 7)
Figure(marks=[graph], layout=fig_layout)


Explicitly setting x and y location for nodes using x and y scales.

Force layout animation is disabled in this case


In [4]:
node_data = list('ABCDEFG')

#using link matrix to set links
link_matrix = np.zeros((7, 7))
xs = LinearScale()
ys = LinearScale()
x = [100, 200, 200, 300, 300, 300, 300]
y = [2, .5, 4, 8, 6, 4, 1]
graph = Graph(node_data=node_data, link_matrix=link_matrix, link_type='line', 
              colors=['orange'] * 7,
              scales={'x': xs, 'y': ys, }, x=x, y=y, 
              directed=False)
Figure(marks=[graph], layout=fig_layout)


Color code nodes using 'color' data attribute


In [5]:
node_data = list('ABCDEFG')

#using link matrix to set links
link_matrix = np.zeros((7, 7))
xs = LinearScale(min=0, max=500)
ys = LinearScale(min=0, max=10)
cs = ColorScale(scheme='Reds')
x = [100, 200, 200, 300, 300, 300, 300]
y = [2, .5, 4, 8, 6, 4, 1]
graph = Graph(node_data=node_data, link_matrix=link_matrix, link_type='line', 
              color=np.random.rand(7),
              scales={'x': xs, 'y': ys, 'color': cs}, x=x, y=y, 
              directed=False)
Figure(marks=[graph], layout=fig_layout)



In [6]:
node_data = list('ABCDEFG')

link_data = [{'source': s, 'target': t, 'value': np.random.rand()} for s, t in np.random.randint(0, 7, (20, 2))]

xs = LinearScale()
ys = LinearScale()
lcs = ColorScale(scheme='Greens')
x = [100, 200, 200, 300, 300, 300, 300]
y = [2, .5, 4, 8, 6, 4, 1]
graph = Graph(node_data=node_data, link_data=link_data, link_type='line',
              colors=['orange'], directed=False, 
              scales={'x': xs, 'y': ys, 'link_color': lcs}, 
              x=x, y=y, color=np.random.rand(7))
Figure(marks=[graph], layout=fig_layout)


Custom node attributes


In [7]:
node_data = [
    {'label': 'A', 'shape': 'circle', 'shape_attrs': {'r': 20}, 'foo': 1},
    {'label': 'Node B', 'shape': 'rect', 'shape_attrs': {'rx': 10, 'ry': 10, 'width': 40}, 'foo': 2},
    {'label': 'C', 'shape': 'ellipse', 'foo': 4},
    {'label': 'D', 'shape': 'rect', 'shape_attrs': {'width': 30, 'height': 30}, 'foo': 100},
]

link_data = [{'source': s, 'target': t, 'value': np.random.rand()} for s, t in np.random.randint(0, 4, (8, 2))]

graph = Graph(node_data=node_data, link_data=link_data, link_distance=150)
Figure(marks=[graph], layout=fig_layout)


{'data': {'shape': 'rect', 'label': 'Node B', 'weight': 4, 'y': 154.53642334306952, 'label_display': 'center', 'shape_attrs': {'rx': 10, 'height': 32, 'ry': 10, 'width': 40}, 'fixed': 0, 'foo': 2, 'index': 1, 'x': 448.92991981020845, 'py': 154.53642334306952, 'value': None, 'px': 448.92991981020845}, 'event': 'element_click'}

Add tooltips on nodes


In [8]:
tooltip = Tooltip(fields=['label', 'foo'], formats=['', '', ''])
graph.tooltip = tooltip

Add a line chart as a tooltip


In [9]:
import bqplot.pyplot as plt
plt.clear()
line = plt.plot(np.cumsum(np.random.randn(20)))
# hover on nodes to see the plot
graph.tooltip = plt.current_figure()

Custom styling of hovered and selected nodes


In [10]:
graph.hovered_style = {'stroke': 'red'}
graph.unhovered_style = {'opacity': '0.4'}

graph.selected_style = {'opacity': '1', 'stroke': 'white', 'stroke-width': '2.5'}

In [11]:
# click on any node to select it (selected attribute gets populated with the index of the selected node)
graph.selected


Out[11]:
[]

Add element click and background click handlers


In [12]:
def print_event(self, target):
    print(target)

graph.on_background_click(print_event)
graph.on_element_click(print_event)

In [ ]:


In [ ]:


In [ ]: