In [1]:
from IPython.display import display
from IPython.html import widgets
from d3networkx import ForceDirectedGraph, EventfulGraph
When an eventful graph is created, create a widget to view it.
In [2]:
def create_widget(graph):
display(ForceDirectedGraph(graph))
EventfulGraph.on_constructed(create_widget)
Code that populates the graph.
In [4]:
BACKGROUND = '#6B8A87'
PARENT_COLOR = '#3E5970'
FACTOR_COLOR = '#424357'
EDGE_COLOR = '#000000'
PRIME_COLOR = '#333241'
CHARGE = -200
MIN_NODE_RADIUS = 15.0
START_NODE_RADIUS = 65.0
is_int = lambda x: int(x) == x
factor = lambda x: [i + 1 for i in range(x-1) if i != 0 and is_int(x / (float(i) + 1.0))]
calc_node_size = lambda x, start_x: max(float(x)/start_x * START_NODE_RADIUS, MIN_NODE_RADIUS)
calc_edge_length = lambda x, parent_x, start_x: calc_node_size(x, start_x) + calc_node_size(parent_x, start_x)
def add_node(graph, value, **kwargs):
graph.add_node(len(graph.node), charge=CHARGE, strokewidth=0, value=value, label=value, font_size='18pt', dy='8', **kwargs)
return len(graph.node) - 1
def add_child_node(graph, x, number, start_number, parent):
index = add_node(graph, x, fill=FACTOR_COLOR, r='%.2fpx' % calc_node_size(x, start_number))
graph.add_edge(index, parent, distance=calc_edge_length(x, number, start_number), stroke=EDGE_COLOR, strokewidth='3px')
return index
def plot_primes(number, start_number=None, parent=None, graph=None, delay=0.0):
start_number = start_number or number
if graph is None:
graph = EventfulGraph(sleep=delay)
graph.node.clear()
parent = parent or add_node(graph, number, fill=PARENT_COLOR, r='%.2fpx' % START_NODE_RADIUS)
factors = factor(number)
if len(factors) == 0:
graph.node[parent]['fill'] = PRIME_COLOR
for x in factors:
index = add_child_node(graph, x, number, start_number, parent)
plot_primes(x, start_number, parent=index, graph=graph)
GUI for factoring a number.
In [5]:
box = widgets.VBox()
header = widgets.HTML(value="<h1>Number Factorizer</h1><br>")
number = widgets.IntSlider(description="Number:", value=100)
speed = widgets.FloatSlider(description="Delay:", min=0.0, max=0.2, value=0.1, step=0.01)
subbox = widgets.HBox()
button = widgets.Button(description="Calculate")
subbox.children = [button]
box.children = [header, number, speed, subbox]
display(box)
box._dom_classes = ['well', 'well-small']
def handle_caclulate(sender):
plot_primes(number.value, delay=speed.value)
button.on_click(handle_caclulate)
In [ ]: