def intermediary_to_schema(tables, relationships, output): """ Transforms and save the intermediary representation to the file chosen. """ dot_file = _intermediary_to_dot(tables, relationships) graph = AGraph() graph = graph.from_string(dot_file) extension = output.split('.')[-1] graph.draw(path=output, prog='dot', format=extension)
def export_table_to_svg(output_directory, tables, output_format='svg', layout_using='neato'): for table in tables: table_dot = '\n' + table.to_dot() dot_file = '{}\n{}\n}}'.format(GRAPH_BEGINNING, table_dot) graph = AGraph(directed=True) graph = graph.from_string(dot_file) graph.draw(path=output_directory + "/{}.{}".format(table.name, output_format), prog=layout_using, format=output_format)
def export_to_svg(output_directory, tables, relationships, svg_per_table, output_name='erd', output_format='svg', layout_using='neato', **kwargs): if svg_per_table: export_table_to_svg(output_directory=output_directory, tables=tables) tables_dot = '\n'.join(table.to_dot() for table in tables) relationships_dot = '\n'.join(relationship.to_dot() for relationship in relationships) dot_file = '{}\n{}\n{}\n}}'.format(GRAPH_BEGINNING, tables_dot, relationships_dot) graph = AGraph() graph = graph.from_string(dot_file) graph.draw(path=output_directory + "/{}.{}".format(output_name, output_format), prog=layout_using, format=output_format)
def show_er_diagram(): er_diagram = BytesIO() er_diagram.name = 'er_diagram' table, relationships = all_to_intermediary(db.Model) dot_file = _intermediary_to_dot(table, relationships) graph = AGraph().from_string(dot_file) graph.draw(er_diagram, prog='dot', format='png') er_diagram.seek(0) return send_file(er_diagram, attachment_filename='er_diagram.png', mimetype='image/png')
def from_dot(filename, strict=True, directed=True, string=None): """ :param filename: :param strict: :param directed: :param string: :return: """ A = AGraph(directed=directed, strict=strict) with open(filename) as reader: data = reader.read() A.from_string(data) return A
def plot_dot_graph(graph, filename=None): """ Plots a graph in graphviz dot notation. :param graph: the dot notation graph :type graph: str :param filename: the (optional) file to save the generated plot to. The extension determines the file format. :type filename: str """ if not plot.pygraphviz_available: logger.error("Pygraphviz is not installed, cannot generate graph plot!") return if not plot.PIL_available: logger.error("PIL is not installed, cannot display graph plot!") return agraph = AGraph(graph) agraph.layout(prog='dot') if filename is None: filename = tempfile.mktemp(suffix=".png") agraph.draw(filename) image = Image.open(filename) image.show()
def display_plot_mpl( viz: AGraph, prog: str = "neato", ax: Axes = None, pixel_size_in: float = 0.01, ) -> Tuple[Figure, Axes]: """ Displays a pygraphviz object using matplotlib. Args: viz: pygraphviz object to render. prog: The graph layout. Avaliable are: dot, neato, fdp, sfdp, twopi and circo ax: Optional matplotlib axes to plot on. pixel_size_in: Scaling multiple for the plot. Returns: IPython Image object. Renders in a notebook. Raises: ImportError: if matplotlib is not installed (optional dependency). """ if Figure is Any: raise ImportError( "display_plot_mpl method requires matplotlib installed.") # bytes: s = viz.draw(format="png", prog=prog) # convert to numpy array array = plt.imread(io.BytesIO(s)) x_dim, y_dim, _ = array.shape # handle passed axis if ax is not None: ax.imshow(array) ax.axis("off") return None, ax # handle new axis f, ax = plt.subplots(1, 1, figsize=(y_dim * pixel_size_in, x_dim * pixel_size_in)) ax.imshow(array) ax.axis("off") f.tight_layout(pad=0.0) return f, ax
def map_input(fu: AGraph, subgraphs: Dict[str, AGraph], simplified_dfg: AGraph) -> Tuple[Dict[str, int], int]: label = fu.graph_attr['label'].strip() preds = simplified_dfg.predecessors(label) tmp = [] for pred in preds: pred_label = pred.attr['label'].strip() if pred_label != label: tmp.append(pred.attr['label']) tmp.sort() out = {} i = 0 for string in tmp: for node in subgraphs[string].nodes(): out[node.get_name()] = i i += 1 return out, i
def display_plot_ipython(viz: AGraph, prog: str = "neato") -> Image: """ Displays a pygraphviz object using ipython. Args: viz: pygraphviz object to render. prog: The graph layout. Avaliable are: dot, neato, fdp, sfdp, twopi and circo Returns: IPython Image object. Renders in a notebook. Raises: ImportError: if IPython is not installed (optional dependency). """ if Image is Any: raise ImportError( "display_plot_ipython method requires IPython installed.") return Image(viz.draw(format="png", prog=prog))
def plot_dot_graph(graph, filename=None): """ Plots a graph in graphviz dot notation. :param graph: the dot notation graph :type graph: str :param filename: the (optional) file to save the generated plot to. The extension determines the file format. :type filename: str """ if not plot.pygraphviz_available: logger.error( "Pygraphviz is not installed, cannot generate graph plot!") return if not plot.PIL_available: logger.error("PIL is not installed, cannot display graph plot!") return agraph = AGraph(graph) agraph.layout(prog='dot') if filename is None: filename = tempfile.mktemp(suffix=".png") agraph.draw(filename) image = Image.open(filename) image.show()
def draw(svg_file, V, A, multigraph=True, showlabel=False, ignore=None): try: from pygraphviz.agraph import AGraph except: print "Failed to load pygraphviz!" return g = AGraph(rankdir="LR", directed=True, bgcolor="white", text="black", font_color="white", ranksep="1.0", nodesep="0.10", strict=not multigraph) #g.node_attr["shape"] = "point" g.node_attr["shape"] = "circle" g.node_attr["color"] = "black" g.node_attr["fontcolor"] = "black" g.node_attr["fontstyle"] = "bold" g.node_attr["penwidth"] = "2.0" M = max(i for (u,v,i) in A if type(i)==int) if multigraph: colors = uniquecolors(2*M) shuffle(colors) for (u,v,i) in A: if ignore != None and (u,v) in ignore: continue assert u != v if i == M or type(i) != int: g.add_edge(u,v,color="black", penwidth=4) else: lbl = str(i) if showlabel else "" g.add_edge(u,v,color=colors[i%len(colors)], penwidth="%d" % 4, label=lbl) else: colors = uniquecolors(M+1) shuffle(colors) links = {} for (u, v, i) in A: if (u,v) not in links: links[u,v] = [] links[u,v].append(i) for (ind, (u, v)) in enumerate(links): if ignore != None and (u,v) in ignore: continue assert u != v if M in links[u,v] or any(type(e) != int for e in links[u,v]): g.add_edge(u,v,color="black", penwidth=4) if len(links[u,v]) != 1: lbl = ",".join(map(str,links[u,v,])) if showlabel else "" g.add_edge(u,v,color=colors[ind%len(colors)], penwidth="%d" % 4, label=lbl) g.draw(svg_file, format="svg", prog="dot") print "SVG file '%s' generated!" % svg_file
def AGraphComputerMultiDiGraph(spsg: nx.MultiDiGraph, cf: Callable) -> AGraph: A = nx.nx_agraph.to_agraph(spsg) A = AGraph(directed=True) A.node_attr["style"] = "filled" A.node_attr["shape"] = "rectangle" A.node_attr["fixedsize"] = "false" A.node_attr["fontcolor"] = "black" for node in spsg.nodes: A.add_node(node_2_string(node)) edges = spsg.edges(data=True) for edge in edges: s, t, data_dict = edge computer_set = data_dict["computers"] for c in computer_set: ss, st = tuple(map(node_2_string, (s, t))) A.add_edge(ss, st) Ae = A.get_edge(ss, st) Ae.attr["color"] = cf(c) Ae.attr["fontcolor"] = cf(c) Ae.attr["label"] = c.__name__ return A
def draw(svg_file, V, A, multigraph=True, showlabel=False, ignore=None): try: from pygraphviz.agraph import AGraph except: print "Failed to load pygraphviz!" return g = AGraph(rankdir="LR", directed=True, bgcolor="white", text="black", font_color="white", ranksep="1.0", nodesep="0.10", strict=not multigraph) #g.node_attr["shape"] = "point" g.node_attr["shape"] = "circle" g.node_attr["color"] = "black" g.node_attr["fontcolor"] = "black" g.node_attr["fontstyle"] = "bold" g.node_attr["penwidth"] = "2.0" M = max(i for (u, v, i) in A if type(i) == int) if multigraph: colors = uniquecolors(2 * M) shuffle(colors) for (u, v, i) in A: if ignore != None and (u, v) in ignore: continue assert u != v if i == M or type(i) != int: g.add_edge(u, v, color="black", penwidth=4) else: lbl = str(i) if showlabel else "" g.add_edge(u, v, color=colors[i % len(colors)], penwidth="%d" % 4, label=lbl) else: colors = uniquecolors(M + 1) shuffle(colors) links = {} for (u, v, i) in A: if (u, v) not in links: links[u, v] = [] links[u, v].append(i) for (ind, (u, v)) in enumerate(links): if ignore != None and (u, v) in ignore: continue assert u != v if M in links[u, v] or any( type(e) != int for e in links[u, v]): g.add_edge(u, v, color="black", penwidth=4) if len(links[u, v]) != 1: lbl = ",".join(map(str, links[u, v, ])) if showlabel else "" g.add_edge(u, v, color=colors[ind % len(colors)], penwidth="%d" % 4, label=lbl) g.draw(svg_file, format="svg", prog="dot") print "SVG file '%s' generated!" % svg_file
def draw_graph(svg_file, V, A, show_labels=False, ignore=None, back=None, loss=None, graph_attrs=None, verbose=False): """Draw an arc-flow graph in .svg format.""" from pygraphviz.agraph import AGraph if ignore is None: ignore = [] if back is None: back = [] if loss is None: loss = [] elif not isinstance(loss, (tuple, list)): loss = [loss] g = AGraph(rankdir="LR", directed=True, bgcolor="white", ranksep="1.0", nodesep="0.10", strict=False) if graph_attrs is not None: for attr, value in graph_attrs.items(): g.graph_attr[attr] = value g.node_attr["shape"] = "ellipse" g.node_attr["color"] = "black" g.node_attr["fontcolor"] = "black" g.node_attr["penwidth"] = "2.0" lbls = sorted(set(i for (u, v, i) in A if i not in loss), key=lambda lbl: (repr(type(lbl)), lbl)) colors = Colors.uniquecolors(len(lbls) + 1, v=0.5, p=0.0) used = set() for (u, v, i) in A: if (u, v) in ignore: continue used.add(u) used.add(v) if (u, v) in back: u, v = v, u d = "back" else: d = "front" if i in loss: g.add_edge(u, v, color="black", style="dashed", penwidth=2, dir=d) else: lbl = str(i) if show_labels else "" color = colors[lbls.index(i) % len(colors)] g.add_edge(u, v, color=color, penwidth=2, label=lbl, dir=d) for v in V: if v not in used: g.add_node(v) g.draw(svg_file, format="svg", prog="dot") if verbose: print("SVG file '{0}' generated!".format(svg_file))
def draw(svg_file, V, A, multigraph=True, showlabel=False, ignore=None, loss=None, verbose=None): """Draws arc-flow graphs in .svg format.""" if loss is None: loss = [i for (u, v, i) in A if not isinstance(i, int)] loss.append(max([i for (u, v, i) in A if isinstance(i, int)] + [-1])) try: from pygraphviz.agraph import AGraph except: raise Exception("Failed to load pygraphviz!") g = AGraph( rankdir="LR", directed=True, bgcolor="white", text="black", font_color="white", ranksep="1.0", nodesep="0.10", strict=not multigraph, ) # g.node_attr["shape"] = "point" g.node_attr["shape"] = "circle" g.node_attr["color"] = "black" g.node_attr["fontcolor"] = "black" g.node_attr["fontstyle"] = "bold" g.node_attr["penwidth"] = "2.0" lbls = list(set(i for (u, v, i) in A)) lbls.sort() M = len(lbls) if multigraph: colors = Colors.uniquecolors(2 * M) random.shuffle(colors) for (u, v, i) in A: if ignore is not None and (u, v) in ignore: continue assert u != v if i in loss: g.add_edge(u, v, color="black", penwidth=4) else: lbl = str(i) if showlabel else "" g.add_edge(u, v, color=colors[lbls.index(i) % len(colors)], penwidth="{0}".format(4), label=lbl) else: colors = Colors.uniquecolors(M + 1) random.shuffle(colors) links = {} for (u, v, i) in A: if (u, v) not in links: links[u, v] = [] links[u, v].append(i) for (ind, (u, v)) in enumerate(links): if ignore is not None and (u, v) in ignore: continue assert u != v if M in links[u, v] or any(not isinstance(e, int) for e in links[u, v]): g.add_edge(u, v, color="black", penwidth=4) if len(links[u, v]) != 1: lbl = ",".join(map(str, links[u, v])) if showlabel else "" g.add_edge(u, v, color=colors[ind % len(colors)], penwidth="{0}".format(4), label=lbl) g.draw(svg_file, format="svg", prog="dot") print "SVG file '{0}' generated!".format(svg_file)
def draw_cfg(self, no_content=False): filepath = f"cfg-img/{self.name}.svg" graph = AGraph(directed=True) ids = set() def add_node( id_: int, color: str, content: str, shape: str, label: str, style: Optional[str] = None, **kwargs, ): kwargs.update(color=color, shape=shape, penwidth="4") if style is not None: kwargs.update(style=style) if no_content: kwargs.update(label=label) else: kwargs.update(label=content, tooltip=label) graph.add_node(id_, **kwargs) def get_id(node: CfgNode) -> int: return id(node) def traverse(node: CfgNode): id_ = get_id(node) if id_ in ids: return ids.add(id_) if isinstance(node, StartNode): add_node( id_, color="green", label="start", shape="ellipse", content=f"{node.requires}", ) graph.add_edge(id_, get_id(node.next_node)) traverse(node.next_node) elif isinstance(node, AssignmentNode): add_node( id_, color="blue", label="assign", shape="rectangle", content=f"{node.var.var} := {node.expression}", ) graph.add_edge(id_, get_id(node.next_node)) traverse(node.next_node) elif isinstance(node, CondNode): add_node( id_, color="red", label="condition", shape="diamond", content=f"{node.condition}", ) graph.add_edge(id_, get_id(node.true_br), label="T") graph.add_edge(id_, get_id(node.false_br), label="F") traverse(node.true_br) traverse(node.false_br) elif isinstance(node, EndNode): add_node( id_, color="black", label="halt", shape="ellipse", content=f"{node.assertion}", ) elif isinstance(node, AssertNode): add_node( id_, color="purple", label="assert", shape="house", content=f"{node.assertion}", ) graph.add_edge(id_, get_id(node.next_node)) traverse(node.next_node) elif isinstance(node, AssumeNode): add_node( id_, color="pink", label="assume", shape="oval", content=f"{node.expression}", ) graph.add_edge(id_, get_id(node.next_node)) traverse(node.next_node) elif isinstance(node, DummyNode): add_node(id_, color="yellow", label="dummy", shape="star", content="???") else: assert False traverse(self.cfg) graph.draw(path=filepath, prog="dot")
def draw_graph(svg_file, V, A, show_labels=False, ignore=None, back=None, loss=None, graph_attrs=None, verbose=False): """Draw an arc-flow graph in .svg format.""" from pygraphviz.agraph import AGraph if ignore is None: ignore = [] if back is None: back = [] if loss is None: loss = [] elif not isinstance(loss, (tuple, list)): loss = [loss] g = AGraph( rankdir="LR", directed=True, bgcolor="white", ranksep="1.0", nodesep="0.10", strict=False ) if graph_attrs is not None: for attr, value in graph_attrs.items(): g.graph_attr[attr] = value g.node_attr["shape"] = "ellipse" g.node_attr["color"] = "black" g.node_attr["fontcolor"] = "black" g.node_attr["penwidth"] = "2.0" lbls = sorted( set(i for (u, v, i) in A if i not in loss), key=lambda lbl: (repr(type(lbl)), lbl) ) colors = Colors.uniquecolors(len(lbls)+1, v=0.5, p=0.0) used = set() for (u, v, i) in A: if (u, v) in ignore: continue used.add(u) used.add(v) if (u, v) in back: u, v = v, u d = "back" else: d = "front" if i in loss: g.add_edge(u, v, color="black", style="dashed", penwidth=2, dir=d) else: lbl = str(i) if show_labels else "" color = colors[lbls.index(i) % len(colors)] g.add_edge(u, v, color=color, penwidth=2, label=lbl, dir=d) for v in V: if v not in used: g.add_node(v) g.draw(svg_file, format="svg", prog="dot") if verbose: print("SVG file '{0}' generated!".format(svg_file))