def test_case(): node0 = Node(0, 'root') node1 = Node(1, 'left') node2 = Node(2, 'right') node3 = Node(3, 'll-child') node4 = Node(4, 'lr-child') node0.left = node1 node0.right = node2 node1.left = node3 node1.right = node4 ga = Animation() ga.add_edge(node0.name, node1.name) ga.add_edge(node0.name, node2.name) ga.add_edge(node1.name, node3.name) ga.add_edge(node1.name, node4.name) ga.next_step() preorder(node0, ga) graphs = ga.graphs() for g in graphs: print(g) output = render(graphs, 'demo', 'png') gif(output, 'demo', 50)
def interactive( animation, size = 320 ): basedir = mkdtemp() basename = join( basedir, 'graph' ) steps = [ Image( path ) for path in render( animation.graphs(), basename, 'png', size ) ] rmtree( basedir ) slider = widgets.IntSlider( min = 0, max = len( steps ) - 1, step = 1, value = 0 ) return widgets.interactive( lambda n: display(steps[ n ]), n = slider )
def render_graph(ga, outfile, size=1024, tempfiletype='png'): ''' Render the gv animation ''' base = os.path.splitext(outfile)[0] graphs = ga.graphs() files = render(graphs, base, tempfiletype, size=size) gif(files, base, 500, size=size)
def render(self) -> None: """Render the state machine visualization to a GIF file.""" graphs = self.animation.graphs() size = 700 with TemporaryDirectory() as tmp_dir: files = gvanim.render( graphs, os.path.join(tmp_dir, "state_machine"), "png", size=size ) # TODO: Replace with removesuffix() when dropping 3.8 support output_path_without_ext = str(self.output_path)[:-4] gvanim.gif(files, output_path_without_ext, delay=50, size=size)
def main(): parser = ArgumentParser(prog='gvanim') parser.add_argument('animation', nargs='?', type=FileType( 'r'), default=stdin, help='The file containing animation commands (default: stdin)') parser.add_argument('--delay', '-d', default='100', help='The delay (in ticks per second, default: 100)') parser.add_argument('basename', help='The basename of the generated file') args = parser.parse_args() ga = Animation() ga.parse(args.animation) gif(render(ga.graphs(), args.basename, 'png'), args.basename, args.delay)
def construct(numbers): ga = Animation() # for visualization root = Node(numbers[0]) for n in numbers[1:]: root = root.add_node(Node(n)) # each time rewrite all nodes. this is not good root.set_animation(ga) ga.next_step(clean=True) # print the result root.print() # save the animation if not os.path.isdir("graphs"): os.mkdir("graphs") graphs = ga.graphs() files = render(graphs, "graphs/figure", 'png') gif(files, "graphs/gif-anim", 50)
def build_max_heap(numbers): size = len(numbers) ga = Animation() # add nodes and edges for i in reversed(range(size)): v = numbers[i] ga.label_node(i + 1, v) if i != 0: ga.add_edge((i + 1) // 2, i + 1) ga.next_step() for i in reversed(range(0, size // 2)): max_heapify(numbers, i, ga) # save graphs = ga.graphs() files = render(graphs, "figure/fig", 'png') gif(files, "figure/building-heap", 50)
def interactive(animation, size=320): basedir = mkdtemp() basename = join(basedir, 'graph') steps = [ Image(path, retina=True) for path in render(animation.graphs(), basename, 'png', size) ] rmtree(basedir) play = widgets.Play( # interval=10, value=50, min=0, max=100, step=1, description="Press play", disabled=False, ) slider = widgets.IntSlider(min=0, max=len(steps) - 1, step=1, value=0) widgets.jslink((play, 'value'), (slider, 'value')) display(play) return widgets.interactive(lambda n: display(steps[n]), n=slider)
def animation(): size = 10 numbers = gen_numbers(size) root = None ga = Animation() # generate tree for n in numbers: root = insert(root, Node(n)) add_nodes(ga, root) ga.highlight_node(n) ga.next_step(clean=True) # delete for n in gen_numbers(size): add_nodes(ga, root) ga.highlight_node(n) ga.next_step(clean=True) root = delete(root, search(root, n)) # save graphs = ga.graphs() files = render(graphs, "figure/figure", 'png') gif(files, "figure/gif-anim", 50)
N = range( 6 ) K = 3 G = dict( ( v, sample( N, K ) ) for v in N ) ga = Animation() for v, adj in G.items(): for u in adj: ga.add_edge( v, u ) ga.label_edge( v, u, '{}:{}'.format(v,u)) ga.next_step() seen = [ False for v in N ] def dfv( v ): ga.highlight_node( v ) ga.next_step() seen[ v ] = True for u in G[ v ]: if not seen[ u ]: ga.highlight_node( v ) ga.highlight_edge( v, u ) ga.next_step() dfv( u ) dfv( 0 ) graphs = ga.graphs() files = render( graphs, 'dfv', 'png' ) gif( files, 'dfv', 50 )
gb.next_step() for u in G[v]: if not seen[u]: gb.add_node(u) gb.add_edge(v, u) ga.highlight_node(u, color='blue') gb.highlight_node(u, color='blue') fringe.put(u) seen[u] = True pre[u] = v color_path(v, ga) color_path(v, gb) addQueueState( fringe, queueStates, "3. Kindknoten von *" + v + "* auf " + queuename + " legen.") ga.next_step() gb.next_step() graphs_a = ga.graphs("circo") files1 = render(graphs_a, os.path.basename(__file__)[:-3] + '_graph', 'svg') graphs_b = gb.graphs("dot") files2 = render(graphs_b, os.path.basename(__file__)[:-3] + '_tree', 'svg') slides(files1, files2, queueStates, os.path.basename(__file__)[:-3])
from gvanim import Animation, render, to_gif N = range( 6 ) K = 3 G = dict( ( v, sample( N, K ) ) for v in N ) ga = Animation() for v, adj in G.items(): for u in adj: ga.add_edge( v, u ) ga.next_step() seen = [ False for v in N ] def dfv( v ): ga.highlight_node( v ) ga.next_step() seen[ v ] = True for u in G[ v ]: if not seen[ u ]: ga.highlight_node( v ) ga.highlight_edge( v, u ) ga.next_step() dfv( u ) dfv( 0 ) graphs = ga.to_graphs() files = render( graphs, 'dfv', 'png' ) to_gif( files, 'dfv', 50 )
for i in range(0, len(w_trace) - 1): edge_tuple = (w_trace[i], w_trace[i + 1]) edge_count[edge_tuple] = edge_count.get(edge_tuple, 0) + 1 # draw graph with calculated values ga = Animation() for event in w_net: text = event + ' (' + str(ev_counter[event]) + ")" ga.label_node(event, text) for preceding in w_net[event]: ga.add_edge(event, preceding) ga.next_step() a = 0 for w_trace in workflow_log: color = choice(colors) for i in range(0, len(w_trace) - 1): # cols = [choice(colors) for _ in range(len(w_trace))] for j in range(0, i + 1): ga.highlight_node(w_trace[j], color=color) ga.highlight_edge(w_trace[j], w_trace[j + 1], color=color) ga.next_step() a += 1 print(a) if a > 30: break graphs = ga.graphs() files = render(graphs, 'dfv', 'png', size=640) gif(files, 'dfv', 10)
def render_path_as_gif(initial_graph_edges, path, img_size=1000, duration_between_steps=0.8, edge_batch_size=1): """ Render final path as a gif (optional) """ ga = gvanim.Animation() for edge in initial_graph_edges: ga.add_edge(edge[0], edge[1]) ga.next_step() visit_times = {} for edge in path: edge = utils.normalize_pair(*edge) visit_times[edge] = 0 drawn_path = [] def draw_path(): for edge in drawn_path: if visit_times[edge] > 1: ga.highlight_edge(*edge, color='blue') else: ga.highlight_edge(*edge, color='red') # for raw_edge in path: # new_edge = utils.normalize_pair(*raw_edge) # draw_path() # ga.highlight_edge(*new_edge, color='red') # drawn_path.append(new_edge) # visit_times[new_edge] += 1 # ga.next_step() cs = edge_batch_size # Chunk size to process paths by for chunk in [ path[cs * i:cs * (i + 1)] for i in range(len(path) // cs + 1) ]: for raw_edge in chunk: new_edge = utils.normalize_pair(*raw_edge) drawn_path.append(new_edge) visit_times[new_edge] += 1 draw_path() ga.highlight_edge(*drawn_path[-1], color='yellow') # Mark last visited edge in red ga.next_step() # Final result draw_path() ga.next_step() render_directory = 'render_files' os.makedirs(render_directory) ga_graphs = ga.graphs() files = gvanim.render(ga_graphs, f'{render_directory}/step', 'png', size=img_size) render_filename = 'render.gif' with imageio.get_writer(render_filename, mode='I', duration=duration_between_steps) as writer: for file in files: image = imageio.imread(file) writer.append_data(image) print( f'Final path rendering available at "src/theoric_app/{render_filename}"' )
def _finish(self): if not self._any_started: return graphs = self._animation.graphs() files = render(graphs, 'graphviz_anim_build', fmt='gif', size=1920) gif(files, 'graphviz_anim_build', delay=50)