# Graphviz FAQ 2002-02-20

Stephen North, Emden Gansner, John Ellson

Note: This is not a tutorial; to understand this you should know how to use the basic features of the tools and languages involved. Please see the user guides for further information.

## General

Q. Where can I see a list of all the attributes that control dot or neato?

See Graph Attributes. There is also information on command-line usage and output formats.

Q. Where can I discuss graphviz?

We have a `graphviz-interest` mailing list. To join, send a message to majordomo@research.att.com containing the line

    subscribe graphviz-interest yourname@host.com

We used to have a message board on one of the big content provider web sites. We are working on grabbing the old messages and installing them on our site.

We don't mind if you register anonymously.

You can browse an online archive of these messages.

Q. I'm trying to make a dot layout larger. How?

Magnification isn't directly supported. We admit this should be fixed. For now you have to adjust individual parameters `fontsize, nodesep` and `ranksep`. For example

               digraph G {
                    graph [fontsize=24];
                    edge  [fontsize=24];
                    node  [fontsize=24];
                    ranksep = 1.5;
                    nodesep = .25;
                    edge [style="setlinewidth(3)"];
                    a -> b -> c;
               }

If you do this, make sure you are not fighting a conflicting graph size setting, like `size="6,6"`.

If you're using Postscript, you can just scale up the output by manually adding a command such as `2 2 scale` where the Postscript environment is set up. Make sure to adjust the `BoundingBox` too if your tools look at this header.

Q. I'm trying to make a neato layout larger. How?

See above regarding font sizes.

You can generally push nodes further apart by changing `elen` (edge lengths). For example, to make it three times the default:

            graph G {
               edge [len=3]
               a -- { b c d }
            }

Q. How can I join or merge certain edge routes?

You can try running `dot -Gconcentrate=true` or you can introduce your own virtual nodes drawn as tiny circles where you want to split or join edges:

    digraph G {
      yourvirtualnode [shape=circle,width=.01,height=.01,label=""];
      a -> yourvirtualnode [arrowhead=none]
      yourvirtualnode -> {b;c}
    }

## Clusters

Q. How can I create edges between cluster boxes?

This only works in graphviz version 1.7 and higher. To make edges between clusters, first set the graph attribute `compound=true`. Then, you can specify a cluster by name as a logical head or tail to an edge. This will cause the edge joining the two nodes to be clipped to the exterior of the box around the given cluster.

For example,

          digraph G {
            compound=true;
            nodesep=1.0;
            subgraph cluster_A {
              a -> b;
              a -> c;
            }
            subgraph cluster_B {
              d -> e;
              f -> e;
            }
            a -> e [ ltail=cluster_A,
                     lhead=cluster_B ];
          }

has an edge going from `cluster_A` to `cluster_B`. If, instead, you say

            a -> e [ltail=cluster_A];

this gives you an edge from `cluster_A` to node `e`. Or you could just specify an `lhead` attribute. The program warns if a cluster specified as a logical node is not defined. Also, if a cluster is specified as a logical head for an edge, the real head must be contained in the cluster, and the real tail must not be. A similar check is done for logical tails. In these cases, the edge is drawn between the real nodes as usual.

Q. Clusters are hard to see.

Set bgcolor=grey (or some other color) in the cluster.

## Output features

Q. I can only get 11x17 output.

It's not us! It's probably your printer setup. If you don't believe this, run `dot -Tps` and looks for the `BoundingBox` header. The coords are in 1/72ths of an inch.

Q. How do I create special symbols and accents in labels?

The following solution only works with the raster drivers that load Truetype or Type1 fonts! (That means, `-Tgif, -Tpng, -Tjpeg`, and possibly `-Tbmp` or `-Txbm` if enabled). Use UTF8 coding, e.g. <verb>¥</verb> for the Yen currency symbol. Example: graph G { yen [label="¥"] }

You can look up other examples in this handy character set reference .

Q. How do I get font and color changes in record labels or other labels?

There's no easy way right now. We're working on it. Sigh.

Q. In plain format, arrowheads are missing. It's a bug that may have solidified into a feature by now. A workaround is to set

          edge [dir=none]

Q. When I have a red edge it shows up as a solid red in PNG and GIF formats, but has a black border when rendered to JPEG.

This is an artifact of JPEG's lossy compression algorithm. JPEG isn't very good for line drawings. PNG is bitmap format of choice. John Ellson wants to deprecate and eventually remove the JPEG driver, but North is reluctant to change anything that people might already rely on.

Q. How can I get custom shapes in my graph?

Please see the Shape HowTo for some approaches. There is no easy way to create custom shapes that work with dot/neato, dotty (Unix or MS-Windows) and Grappa (the Java front end), because they don't share any universal back end structure. We're thinking about it.

Q. How can I get some display feature (such as bold lines) in dotty?

If it's not there already, there's probably no easy way to do it except by rolling up your sleeves and hacking the dotty (lefty script) code that interprets and renders graphical attributes. This is problematic for the same reason as above: there's no universal low-level driver layer that is shared across all the graphviz tools. Sorry, we already feel bad about it.

Q. How can I get rid of the little circles on edges ("edge handles") in dotty?

Edit the file dotty.lefty and change the line that says: 'edgehandles' = 1; to 'edgehandles' = 0; it's around line 110.

Q. I already have all the coordinates for the nodes and edges of my graph and just want to use dot, neato, or dotty to render it. How?

Put the graph with layout attributes into a dot file. Then run `neato -s -n2`. For example:

    neato -s -n2 -Tgif file.dot -o file.gif

Note that if an edge does not have a pos attribute defined, neato will perform whatever edge routing it would normally do.

Q. I already have all the coordinates for the nodes, and I want dot or neato to route the edges.

It's not really too convenient to use dot for this. It is possible to use neato for this, running neato -s -n For example:

    neato -s -n -Tgif file.dot -o file.gif

neato will use the node positions, but use its technique for routing the edges. There are several things to note. First, the neato edge router is different from dot's. Without the built-in top-down bias, it doesn't do as good a job of avoiding edge overlaps and, at present, it doesn't handle multi-edges at all. Second, by default, neato uses straight lines as edges. To get spline routing, you have to specify -Gsplines=true. And this will only work if none of the nodes overlap. Since the input graph supplies fixed node positions, it is the user's task to insure this.

Q. I already have all the coordinates for the nodes and edges of my graph and just want to use dotty to render it. How?

Just run dotty on it. Dotty will use the given pos attributes.

## Problems

Q. How can I avoid node overlaps in neato?

    neato -Goverlap=false
    neato -Goverlap=scale

In the first instance, neato will use a Voronoi diagram-based technique to remove overlaps. In the second, it scales up node positions, but not node shapes, until there are no overlaps. The first technique uses less space; the second preserves symmetries.

Q. How can I avoid node-edge overlaps in neato?

    neato -Goverlap=false/scale -Gsplines=true -Gsep=.1

    The sep argument is the node-edge separation as
    a ratio of a node's bounding box. (Don't ask why this
    isn't just a constant!)  Note that this option really
    slows down neato, so should be used sparingly and only
    with modest-sized graphs.

    Q. Neato runs forever on a certain example.

    It could be that your graph is too big, or it could be
    that neato is cycling.
    Run neato -v to observe its progress.
    Neato uses an anti-cycling heuristic, so cycling shouldn't occur.
    If your graph is small and the -v output indicates cycling, please submit
    the graph as a bug report, so we can consider additional heuristics.
    In addition, there are ways to defeat the cycling by causing neato to
    use different initial conditions:

    neato -Gstart=3

    or to stop earlier:

    neato -Gepsilon=.01
    neato -Gmaxiter=500

    If it's a large example, the problem is that neato (which is nearly the same
    algorithm as multidimensional scaling) is at least quadratic in time
    complexity.  The spline router is even worse: O(N^3).
    So don't run neato -Gsplines=true unless you're willing to pay for it.

    Q. Dot runs forever on a certain example.

    Try dot -v to observe its progress.

    Note that it's possible to make graphs whose layout or even parsing
    is quadratic in the input size. For example, in dot,

    digraph G {
        a -> b -> c -> .... -> x -> y -> z
        a -> z
        b -> z
        c -> z
        /* and so on... */
    	x -> z
    }

    The total edge length (therefore the layout time) of
    this as a ranked graph is quadratic in the number of nodes.

    You probably won't encounter the following, but it is also possible
    to construct graphs whose parsing takes quadratic time, by appending
    attributes to nodes and edges after the graph has been loaded.
    For example:

    digraph G {
        /* really big graph goes here... */
        n0 -> n1 -> ... -> n999999999;

        n0 [attr0="whatever"]
        n0 [attr1="something else"]
        /* and so on with many more attributes */
    }

    The addition of attr0 touches every node of the graph.
    Then the addition of attr1 touches every node again, and so on.

    Q.  Neato has unnecessary edge crossings, or does something bad.

    Neato and all similar virtual physical model algorithms rely
    on heuristic solutions of optimization problems. The better
    the solution, the longer it takes to find. Unfortunately, it
    is also possible for these heuristics to get stuck in local
    minima. Also, it is heavily influenced by the initial position
    of the nodes. It is quite possible that if you run neato again,
    but with a different random seed value,
    or more iterations, you'll get a better layout.  For example:

    neato -Gstart=5 file.dot -Tps -o file.ps
    neato -Gepsilon=.0000001 file.dot -Tps -o file.ps