def read_hypergraph(string): """ Read a hypergraph from a string in dot format. Nodes and edges specified in the input will be added to the current hypergraph. @type string: string @param string: Input string in dot format specifying a graph. @rtype: hypergraph @return: Hypergraph """ hgr = hypergraph() dotG = pydot.graph_from_dot_data(string) # Read the hypernode nodes... # Note 1: We need to assume that all of the nodes are listed since we need to know if they # are a hyperedge or a normal node # Note 2: We should read in all of the nodes before putting in the links for each_node in dotG.get_nodes(): if 'hypernode' == each_node.get('hyper_node_type'): hgr.add_node(each_node.get_name()) elif 'hyperedge' == each_node.get('hyper_node_type'): hgr.add_hyperedge(each_node.get_name()) # Now read in the links to connect the hyperedges for each_link in dotG.get_edges(): if hgr.has_node(each_link.get_source()): link_hypernode = each_link.get_source() link_hyperedge = each_link.get_destination() elif hgr.has_node(each_link.get_destination()): link_hypernode = each_link.get_destination() link_hyperedge = each_link.get_source() hgr.link(link_hypernode, link_hyperedge) return hgr
def save_graph(graph_str, dest_file, fmt=None, image_ratio=None): """Render a graph to an image file. Args: graph_str (str): Dot-language graph string. dest_file (str): Filepath to save the graph to. fmt (str): Format, eg "png", "jpg". image_ratio (float): Image ratio. Returns: String representing format that was written, such as 'png'. """ try: g = pydot.graph_from_dot_data(graph_str)[0] except IndexError: import traceback traceback.print_exc() raise Exception("Could not produce graph") # determine the dest format fmt = os.path.splitext(dest_file)[1].lower().strip('.') or "png" if fmt not in g.formats: raise Exception("Unsupported graph format: '%s'" % fmt) if image_ratio: g.set_ratio(str(image_ratio)) g.write(dest_file, format=fmt) return fmt
def save_graph(graph_str, dest_file, fmt=None, image_ratio=None): """Render a graph to an image file. Args: graph_str (str): Dot-language graph string. dest_file (str): Filepath to save the graph to. fmt (str): Format, eg "png", "jpg". image_ratio (float): Image ratio. Returns: String representing format that was written, such as 'png'. """ g = pydot.graph_from_dot_data(graph_str) # determine the dest format if fmt is None: fmt = os.path.splitext(dest_file)[1].lower().strip('.') or "png" if hasattr(g, "write_" + fmt): write_fn = getattr(g, "write_" + fmt) else: raise Exception("Unsupported graph format: '%s'" % fmt) if image_ratio: g.set_ratio(str(image_ratio)) write_fn(dest_file) return fmt
def read(string): """ Read a graph from a string in Dot language and return it. Nodes and edges specified in the input will be added to the current graph. @type string: string @param string: Input string in Dot format specifying a graph. @rtype: graph @return: Graph """ dotG = pydot.graph_from_dot_data(string) if (dotG.get_type() == "graph"): G = graph() elif (dotG.get_type() == "digraph"): G = digraph() elif (dotG.get_type() == "hypergraph"): return read_hypergraph(string) else: raise InvalidGraphType # Read nodes... # Note: If the nodes aren't explicitly listed, they need to be for each_node in dotG.get_nodes(): G.add_node(each_node.get_name()) for each_attr_key, each_attr_val in each_node.get_attributes().items(): G.add_node_attribute(each_node.get_name(), (each_attr_key, each_attr_val)) # Read edges... for each_edge in dotG.get_edges(): # Check if the nodes have been added if not G.has_node(each_edge.get_source()): G.add_node(each_edge.get_source()) if not G.has_node(each_edge.get_destination()): G.add_node(each_edge.get_destination()) # See if there's a weight if 'weight' in each_edge.get_attributes().keys(): _wt = each_edge.get_attributes()['weight'] else: _wt = 1 # See if there is a label if 'label' in each_edge.get_attributes().keys(): _label = each_edge.get_attributes()['label'] else: _label = '' G.add_edge((each_edge.get_source(), each_edge.get_destination()), wt = _wt, label = _label) for each_attr_key, each_attr_val in each_edge.get_attributes().items(): if not each_attr_key in ['weight', 'label']: G.add_edge_attribute((each_edge.get_source(), each_edge.get_destination()), \ (each_attr_key, each_attr_val)) return G
def save_graph(graph_str, dest_file, fmt=None, image_ratio=None): """Render a graph to an image file. Args: graph_str (str): Dot-language graph string. dest_file (str): Filepath to save the graph to. fmt (str): Format, eg "png", "jpg". image_ratio (float): Image ratio. Returns: String representing format that was written, such as 'png'. """ # Disconnected edges can result in multiple graphs. We should never see # this - it's a bug in graph generation if we do. # graphs = pydot.graph_from_dot_data(graph_str) if not graphs: raise RuntimeError("No graph generated") if len(graphs) > 1: path, ext = os.path.splitext(dest_file) dest_files = [] for i, g in enumerate(graphs): try: dest_file_ = "%s.%d%s" % (path, i + 1, ext) save_graph_object(g, dest_file_, fmt, image_ratio) dest_files.append(dest_file_) except: pass raise RuntimeError( "More than one graph was generated; this probably indicates a bug " "in graph generation. Graphs were written to %r" % dest_files ) # write the graph return save_graph_object(graphs[0], dest_file, fmt, image_ratio)
def read(string): """ Read a graph from a string in Dot language and return it. Nodes and edges specified in the input will be added to the current graph. @type string: string @param string: Input string in Dot format specifying a graph. @rtype: graph @return: Graph """ dotG = pydot.graph_from_dot_data(string) # This is awful, however there seems to be a major incompatibility with pygraph # and current pydot. Pydot now returns a list of graphs from a dot string. Rather # than possibly rewrite a big chunk of this lib, we'll just use the first graph. # Since rez only makes single graphs anyway, this should suffice. # # https://github.com/nerdvegas/rez/issues/884 # # <hack> if isinstance(dotG, list): dotG = dotG[0] # </endhack> if (dotG.get_type() == "graph"): G = graph() elif (dotG.get_type() == "digraph"): G = digraph() elif (dotG.get_type() == "hypergraph"): return read_hypergraph(string) else: raise InvalidGraphType # Read nodes... # Note: If the nodes aren't explicitly listed, they need to be for each_node in dotG.get_nodes(): G.add_node(each_node.get_name()) for each_attr_key, each_attr_val in each_node.get_attributes().items(): G.add_node_attribute(each_node.get_name(), (each_attr_key, each_attr_val)) # Read edges... for each_edge in dotG.get_edges(): # Check if the nodes have been added if not G.has_node(each_edge.get_source()): G.add_node(each_edge.get_source()) if not G.has_node(each_edge.get_destination()): G.add_node(each_edge.get_destination()) # See if there's a weight if 'weight' in each_edge.get_attributes().keys(): _wt = each_edge.get_attributes()['weight'] else: _wt = 1 # See if there is a label if 'label' in each_edge.get_attributes().keys(): _label = each_edge.get_attributes()['label'] else: _label = '' G.add_edge((each_edge.get_source(), each_edge.get_destination()), wt=_wt, label=_label) for each_attr_key, each_attr_val in each_edge.get_attributes().items(): if not each_attr_key in ['weight', 'label']: G.add_edge_attribute((each_edge.get_source(), each_edge.get_destination()), \ (each_attr_key, each_attr_val)) return G
def read(string): """ Read a graph from a string in Dot language and return it. Nodes and edges specified in the input will be added to the current graph. @type string: string @param string: Input string in Dot format specifying a graph. @rtype: graph @return: Graph """ dotG = pydot.graph_from_dot_data(string) if (dotG.get_type() == "graph"): G = graph() elif (dotG.get_type() == "digraph"): G = digraph() elif (dotG.get_type() == "hypergraph"): return read_hypergraph(string) else: raise InvalidGraphType # Read nodes... # Note: If the nodes aren't explicitly listed, they need to be for each_node in dotG.get_nodes(): G.add_node(each_node.get_name()) for each_attr_key, each_attr_val in each_node.get_attributes().items(): G.add_node_attribute(each_node.get_name(), (each_attr_key, each_attr_val)) # Read edges... for each_edge in dotG.get_edges(): # Check if the nodes have been added if not G.has_node(each_edge.get_source()): G.add_node(each_edge.get_source()) if not G.has_node(each_edge.get_destination()): G.add_node(each_edge.get_destination()) # See if there's a weight if 'weight' in each_edge.get_attributes().keys(): _wt = each_edge.get_attributes()['weight'] else: _wt = 1 # See if there is a label if 'label' in each_edge.get_attributes().keys(): _label = each_edge.get_attributes()['label'] else: _label = '' G.add_edge((each_edge.get_source(), each_edge.get_destination()), wt=_wt, label=_label) for each_attr_key, each_attr_val in each_edge.get_attributes().items(): if not each_attr_key in ['weight', 'label']: G.add_edge_attribute((each_edge.get_source(), each_edge.get_destination()), \ (each_attr_key, each_attr_val)) return G