Search code examples
pythongraphvizpygraphviz

How do I make an undirected graph in pygraphviz?


I am trying to generate undirected graphs in pygraphviz but have been unsuccessful. It seems that no matter what I do, the graph always turns out directed.

Example #1
G = pgv.AGraph(directed=False)
G.is_directed()  # true

Example #2
G = pgv.AGraph()
G.to_undirected().is_directed()  # True

Example #3
G = pgv.AGraph(directed=False)
G.graph_attr.update(directed=False)
G.is_directed()  # true

I have no idea why something so trivial could not be working. What I am doing wrong?


Solution

  • I'm having the same problem on pygraphviz 1.2, but I have a workaround.

    If you specify the desired graph type as an empty graph using the DOT language (e.g. graph foo {}), and pass it to the constructor of AGraph, then pygraphviz respects the graph type, even though it may ignore it when given as a keyword argument (as on my environment).

    >>> import pygraphviz as pgv
    >>> foo = pgv.AGraph('graph foo {}')
    >>> foo.is_directed()
    False
    >>> foo.add_edge('A', 'B')
    >>> print foo
    graph foo {
            A -- B;
    }
    

    The workaround works for the strict argument, too, which is also being ignored on my environment.

    Use the following function instead of pgv.AGraph to have the same API:

    def AGraph(directed=False, strict=True, name='', **args):
        """Fixed AGraph constructor."""
    
        graph = '{0} {1} {2} {{}}'.format(
            'strict' if strict else '',
            'digraph' if directed else 'graph',
            name
        )
    
        return pgv.AGraph(graph, **args)