wolffd@0: wolffd@0: Graphviz FAQ 2008-06-06 wolffd@0: wolffd@0: wolffd@0:

Graphviz FAQ 2008-06-06

wolffd@0: wolffd@0: The Graphviz Project wolffd@0:

wolffd@0: Note: wolffd@0: This is not a tutorial; to understand the following, you should wolffd@0: know how to use the basic features of the tools and wolffd@0: languages involved. Please see the wolffd@0: wolffd@0: user guides and documentation for further information or the wolffd@0: resources page wolffd@0: for a partial list of compatible tools and packages. wolffd@0: wolffd@0:

General

wolffd@0: wolffd@0: wolffd@0: Q1. Where can I see a list of all the attributes that control dot or neato? wolffd@0: wolffd@0: wolffd@0:

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

wolffd@0: wolffd@0: wolffd@0: Q2. Where can I discuss Graphviz? wolffd@0: wolffd@0:

wolffd@0: We run a mailing list. wolffd@0:

wolffd@0: To subscribe or unsubscribe, visit the wolffd@0: graphviz-interest mailman control page. See also the general wolffd@0: wolffd@0: instructions for mailman. wolffd@0:

wolffd@0: You can also see the wolffd@0: wolffd@0: archive. wolffd@0:

wolffd@0: You may wish to use a Yahoo or Hotmail account if you're concerned wolffd@0: about spam. We also run anti-spam filters, and rewrite @ wolffd@0: as at to keep verbatim addresses out of the archive. wolffd@0:

wolffd@0: Please, please, please, do not torment the mailing list with beginner's wolffd@0: questions. First, check this FAQ and the wolffd@0: wolffd@0: message archive carefully. wolffd@0: If you are desperate, or better yet, if you have constructive advice, wolffd@0: please send a message to the graphviz-devel mailing list. wolffd@0:

wolffd@0: Also, if a program crashes or you get an abort or something strange occurs wolffd@0: and you are fairly comfortable using the tools: wolffd@0:

wolffd@0:

wolffd@0: wolffd@0: Q3. I'm trying to make a layout larger. How? wolffd@0: wolffd@0:

wolffd@0: There are various ways to increase the size of a layout. In doing this, wolffd@0: one has to decide if the sizes of the nodes and text should be wolffd@0: increased as well. wolffd@0:

wolffd@0: One approach is to adjust individual wolffd@0: parameters such as fontsize, nodesep and ranksep. wolffd@0: For example, wolffd@0:

wolffd@0:            digraph G {
wolffd@0:                 graph [fontsize=24];
wolffd@0:                 edge  [fontsize=24];
wolffd@0:                 node  [fontsize=24];
wolffd@0:                 ranksep = 1.5;
wolffd@0:                 nodesep = .25;
wolffd@0:                 edge [style="setlinewidth(3)"];
wolffd@0:                 a -> b -> c;
wolffd@0:            }
wolffd@0: 
wolffd@0: If you do this, make sure you are not fighting a conflicting graph wolffd@0: size setting, like size="6,6", which will then scale wolffd@0: everything back down. wolffd@0:

wolffd@0: If you are using fdp or neato, increasing the edge len will tend to wolffd@0: expand the layout. wolffd@0:

wolffd@0:         graph G {
wolffd@0:            edge [len=3]
wolffd@0:            a -- { b c d }
wolffd@0:         }
wolffd@0: 
wolffd@0: For twopi and circo, there are other parameters such as wolffd@0: ranksep which can be used. See the wolffd@0: wolffd@0: graph attributes. wolffd@0:

wolffd@0: You can also use the ratio attribute. If you set the size wolffd@0: attribute to the desired drawing size, and then set ratio=fill, node wolffd@0: positions are scaled separately in x and y until the drawing fills the wolffd@0: specified size. Note that node sizes stay the same. If, instead, wolffd@0: you set ratio=expand, the layout is uniformly scaled up in x and y wolffd@0: until at least one dimension fits size. wolffd@0:

wolffd@0: If you specify the size attribute but end it with an exclamation wolffd@0: mark (!), the final drawing will be scaled up uniformly in x and y wolffd@0: until at least one dimension fits size. Note that everything is wolffd@0: scaled up, including text and node sizes. wolffd@0:

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

wolffd@0: wolffd@0: Q4. How can I join or merge certain edge routes in dot? wolffd@0: wolffd@0:

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

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

wolffd@0: wolffd@0: Q. How can I generate graph layouts in PDF? wolffd@0: wolffd@0:

wolffd@0: Recent versions of graphviz with the CairoPango based drivers wolffd@0: can generate PDF directly with the -Tpdf command line option. wolffd@0: This this first. wolffd@0:

wolffd@0: Otherwise, create Postscript output, then use an external converter from wolffd@0: Postscript to PDF. wolffd@0: For example,
wolffd@0: dot -Tps | epsf2pdf -o file.pdf
wolffd@0: Note that URL tags are respected, to allow clickable PDF objects. wolffd@0:

wolffd@0: If your intention is to use the figure as PDF in some document preparation wolffd@0: system, such as pdflatex, it is very important to use -Tps2 rather than wolffd@0: -Tps. In general, if you really want PDF output, that is, you would like wolffd@0: to have a -Tpdf flag, use -Tps2 before converting to PDF. wolffd@0:

wolffd@0: In the diagram below, the shaded nodes will contain bad output.
wolffd@0: wolffd@0:

wolffd@0: wolffd@0: Q. How can I make duplicate nodes? wolffd@0: wolffd@0:

wolffd@0: Make unique nodes with duplicate labels. wolffd@0:

wolffd@0:       digraph G {
wolffd@0:             node001 [label = "A"];
wolffd@0:             node002 [label = "A"];
wolffd@0: 			node001 -> node002;
wolffd@0: 	  }
wolffd@0: 
wolffd@0:

wolffd@0: wolffd@0: Q. How can I set a graph or cluster label without its propagating to all sub-clusters? wolffd@0: wolffd@0:

wolffd@0: Set the label at the end of the graph (before the closing brace), after all wolffd@0: its contents have been defined. (We admit it seems desirable to define some wolffd@0: special syntax for non-inherited attribute settings.) wolffd@0:

wolffd@0: wolffd@0: Q5. How can I draw multiple parallel edges in neato? wolffd@0: wolffd@0:

wolffd@0: This is possible when the splines attribute is false, which wolffd@0: is the default. When splines=true, we have no good answer but wolffd@0: we are working on it. One trick which is sometimes sufficient is to wolffd@0: specify multiple colors for the edge. This will a produce set of tightly wolffd@0: parallel splines, each in its specified color. Read about the wolffd@0: color wolffd@0: attribute for more information. wolffd@0: wolffd@0:

Clusters

wolffd@0: wolffd@0: wolffd@0: Q. How can I create edges between cluster boxes? wolffd@0: wolffd@0:

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

wolffd@0: For example, wolffd@0: wolffd@0:

wolffd@0:       digraph G {
wolffd@0:         compound=true;
wolffd@0:         nodesep=1.0;
wolffd@0:         subgraph cluster_A {
wolffd@0:           a -> b;
wolffd@0:           a -> c;
wolffd@0:         }
wolffd@0:         subgraph cluster_B {
wolffd@0:           d -> e;
wolffd@0:           f -> e;
wolffd@0:         }
wolffd@0:         a -> e [ ltail=cluster_A,
wolffd@0:                  lhead=cluster_B ];
wolffd@0:       }
wolffd@0: 
wolffd@0: wolffd@0: has an edge going from cluster_A to wolffd@0: cluster_B. If, instead, you say wolffd@0: wolffd@0:
wolffd@0:         a -> e [ltail=cluster_A];
wolffd@0: 
wolffd@0: wolffd@0: this gives you an edge from cluster_A to node wolffd@0: e. Or you could just specify wolffd@0: an lhead attribute. wolffd@0: wolffd@0: The program warns if a cluster specified as a wolffd@0: logical node is not defined. wolffd@0: Also, if a cluster is specified as a logical wolffd@0: head for an edge, the real wolffd@0: head must be contained in the cluster, and wolffd@0: the real tail must not be. wolffd@0: A similar check is done for logical tails. In wolffd@0: these cases, the edge wolffd@0: is drawn between the real nodes as usual. wolffd@0:

wolffd@0: wolffd@0: Q6. Clusters are hard to see. wolffd@0: wolffd@0:

wolffd@0: Set bgcolor=grey wolffd@0: (or some other color) wolffd@0: in the cluster. wolffd@0:

wolffd@0: wolffd@0: Q7. How can I symmetrize (balance) tree layouts? wolffd@0: wolffd@0:

wolffd@0: When a tree node has an even number of children, it isn't necessarily wolffd@0: centered above the two middle ones. If you know the order of the children, wolffd@0: a simple hack is to introduce new, invisible middle nodes to re-balance wolffd@0: the layout. The connecting edges should also be invisible. For example: wolffd@0:

wolffd@0: digraph G {
wolffd@0: a -> b0;
wolffd@0: xb [label="",width=.1,style=invis]
wolffd@0: a -> xb [style=invis];
wolffd@0: a -> b1;
wolffd@0: {rank=same b0 ->  xb -> b1 [style=invis]}
wolffd@0: b0 -> c0;
wolffd@0: xc [label="",width=.1,style=invis]
wolffd@0: b0 -> xc [style=invis];
wolffd@0: b0 -> c1;
wolffd@0: {rank=same c0 ->  xc -> c1 [style=invis]}
wolffd@0: }
wolffd@0: 
wolffd@0: This trick really ought to be build into our solver (and made wolffd@0: independent of the order of the children, and available for wolffd@0: layouts other than trees, too). wolffd@0: wolffd@0:

Output features

wolffd@0: wolffd@0: wolffd@0: Q8. How can I get high quality (antialiased) output? wolffd@0: wolffd@0:

wolffd@0: The easiest thing may be to make the layout in Postscript (option -Tps), wolffd@0: then run through Ghostview with wolffd@0: antialiasing enabled. The important command line options are wolffd@0: -dTextAlphaBits=4 -dGraphicsAlphaBits=4 wolffd@0: (4 is the highest level of antialiasing allowed - see the wolffd@0: Ghostview documentation). wolffd@0: The full command line to render a raster could be something like: wolffd@0:

wolffd@0: gs -q -dNOPAUSE -dBATCH -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=png16m -sOutputFile=file.png file.ps
wolffd@0: 
wolffd@0:

wolffd@0: On Mac OS X, the pixelglow port wolffd@0: uses Apple's Quartz renderer, which enables antialiasing. It also provides a beautiful document container for its user interface. (One downside is wolffd@0: that you can't run Pixelglow Graphviz as a web server or other background wolffd@0: process if your Mac has 3D graphics, because Quartz wants to get this resource wolffd@0: to accelerate rendering. Another problem is that as of this writing, wolffd@0: Pixelglow Graphviz hasn't been updated in a long time, maybe mid 2004.) wolffd@0:

wolffd@0: On the Linux bleeding edge, Graphviz has an optional plugin to use wolffd@0: the cairo back end, wolffd@0: which has antialiased, path-based graphics. If you want this, wolffd@0: you must install cairo, which is not part of Graphviz. Cairo is wolffd@0: available in recent versions of Fedora linux, or it can be built wolffd@0: from source. wolffd@0:

wolffd@0: wolffd@0: Q9. I can only get 11x17 output. wolffd@0: wolffd@0:

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

wolffd@0: wolffd@0: Q10. How do I create special symbols and accents in labels? wolffd@0: wolffd@0:

wolffd@0: The following solution only works with the wolffd@0: raster drivers that load Truetype or Type1 wolffd@0: fonts! (That means, -Tgif, -Tpng, -Tjpeg, and possibly wolffd@0: -Tbmp or -Txbm if enabled). wolffd@0: wolffd@0: Use UTF8 coding, e.g. ¥ for the Yen currency symbol ¥. wolffd@0: Example: wolffd@0: wolffd@0:

wolffd@0:       graph G {
wolffd@0:             yen [label="¥"]
wolffd@0:       }
wolffd@0: 
wolffd@0:

wolffd@0: You can look up other examples in this handy wolffd@0: wolffd@0: character set reference. wolffd@0:

wolffd@0: wolffd@0: Q. More generally, how do I use non-ASCII character sets? wolffd@0: wolffd@0:

wolffd@0: The following applies to Graphviz 2.8 and later. (In older versions wolffd@0: of Graphviz, you can sometimes get away with simply putting wolffd@0: Latin-1 or other UTF-8 characters in the input stream, but the wolffd@0: results are not always correct.) wolffd@0:

wolffd@0: Input: the general idea is to find the wolffd@0: Unicode wolffd@0: value for the glyph you want, and enter it within a text wolffd@0: string "...." or HTML-like label <...>. wolffd@0:

wolffd@0: For example, the mathematical forall sign (∀) has the value 0x2200. wolffd@0: There are several ways this can be inserted into a file. wolffd@0: One is to write out the ASCII representation: "&#<nnn>;" where <nnn> wolffd@0: is the decimal representation of the value. The decimal value of 0x2200 is 8704, wolffd@0: so the character can be specified as "&#8704;" . Alternatively, Graphviz wolffd@0: accepts UTF-8 encoded input. In the case of forall, its UTF-8 representation wolffd@0: is 3 bytes whose decimal values are 226 136 128. For convenience, you wolffd@0: would probably enter this using your favorite editor, tuned to your character set wolffd@0: of choice. You can then use the wolffd@0: iconv program to map the graph from your character set to UTF-8 or Latin-1. wolffd@0:

wolffd@0: We also accept the HTML symbolic names for Latin-1 characters as suggested wolffd@0: above. wolffd@0: (Go to http://www.research.att.com/~john/docs/html/index.htm and click wolffd@0: on Special symbols and Entities) For example, the cent sign (unicode wolffd@0: and Latin-1 value decimal 162 can be inserted as wolffd@0:

wolffd@0: &cent;
wolffd@0: 
wolffd@0:

wolffd@0: Note that the graph file must always be a plain text document wolffd@0: not a Word or other rich format file. Any characters not enclosed in "..." wolffd@0: or <...> must be ordinary ASCII characters. In particular, all of the DOT wolffd@0: keywords such as digraph or subgraph must be ASCII. wolffd@0:

wolffd@0: Because we cannot always guess the encoding, you should set the graph wolffd@0: attribute charset to wolffd@0: UTF-8, wolffd@0: Latin1 wolffd@0: (alias ISO-8859-1 or ISO-IR-100) wolffd@0: or wolffd@0: Big-5 for wolffd@0: Traditional Chinese. This can be done in the graph file or on the command line. wolffd@0: For example charset=Latin1. wolffd@0:

wolffd@0: Output: It is essential that a font which has the glyphs for your wolffd@0: specified characters is available at final rendering time. wolffd@0: The choice of this font depends on the target code generator. wolffd@0: For the gd-based raster generators (PNG, GIF, etc.) you need a wolffd@0: TrueType or Type-1 font file on the machine running the Graphviz program. wolffd@0: If Graphviz is built with the fontconfig wolffd@0: library, it will be used to find the specified font. Otherwise, Graphviz will wolffd@0: look in various default directories for the font. The directories to be wolffd@0: searched include those specified by the fontpath attribute, wolffd@0: related environment or shell variables wolffd@0: (see the fontpath entry), wolffd@0: and known system font directories. wolffd@0: The table wolffd@0: wolffd@0: http://www.graphviz.org/doc/char.html wolffd@0: points out that these glyphs are from the times.ttf font. wolffd@0: With fontconfig, it's hard to specify this font. Times usually gets wolffd@0: resolved to Adobe Type1 times, which doesn't have all the glyphs seen on that page.) wolffd@0: wolffd@0:

wolffd@0: For Postscript, the input must be either the ASCII subset of UTF-8 wolffd@0: or Latin-1. (We have looked for more general solutions, but it wolffd@0: appears that UTF-8 and Unicode are handled differently for every wolffd@0: kind of font type in Postscript, and we don't have time to hack wolffd@0: this case-by-case. If someone wants to volunteer to work on this, let us know.) wolffd@0:

wolffd@0: For SVG output, we just pass the raw UTF-8 (or other encoding) wolffd@0: straight through to the generated code. wolffd@0:

wolffd@0: Non-ASCII characters probably won't ever work in Grappa wolffd@0: or dotty, which have their own back end rendering. wolffd@0: (Though, Java supports UTF-8, so there's a chance wolffd@0: Grappa also handles raw UTF-8 strings.) wolffd@0:

wolffd@0: As you can see, this is a sad state of affairs. wolffd@0: Our plan is to eventually migrate Graphviz to the wolffd@0: pango text formatting wolffd@0: library, to ameliorate the worst of these complications. wolffd@0:

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

wolffd@0: This is not possible in record shapes. However, you can do this using wolffd@0: wolffd@0: HTML-like labels. The granularity of changes is still at the cell level, wolffd@0: but by playing with cell spacing and padding, you can get pretty much wolffd@0: the effect you want. The intention is to support arbitrary font changes wolffd@0: within running text in the not-too-distant future. wolffd@0: wolffd@0:

wolffd@0: wolffd@0: Q12. In plain format, splines do not touch the nodes (arrowheads are missing). wolffd@0: wolffd@0:

wolffd@0: Edges are specified as the main spline and, if necessary, arrowheads wolffd@0: which actually abut the node. If the arrowheads are not given, drawing wolffd@0: the edge spline will leave a gap between the edge and the node. wolffd@0: This is a bug which has now solidified into a feature. wolffd@0: A workaround is to set wolffd@0: wolffd@0:

wolffd@0:       edge [dir=none]
wolffd@0: 
wolffd@0: Since the edges have no arrowheads, the spline specification will go wolffd@0: all the way to both nodes. wolffd@0:

wolffd@0: wolffd@0: Q13. Record nodes are drawn differently in dot and neato when rankdir=LR. wolffd@0: wolffd@0:

wolffd@0: It's true. dot -Grankdir=LR rotates record nodes so that their top level wolffd@0: fields are still listed across levels. rankdir=LR has no effect in neato. wolffd@0: One workaround is wolffd@0: wolffd@0: HTML-like records (they don't rotate; the downside is that wolffd@0: you have to write in XML). Another workaround is to enclose wolffd@0: record labels in { } to rotate/unrotate the record contents. See also, wolffd@0: How To Avoid Foolish Consistency wolffd@0: by Scott Berkun (Microsoft Corp.) wolffd@0:

wolffd@0: wolffd@0: Q14. How can I print a big graph on multiple pages? wolffd@0: wolffd@0:

wolffd@0: The page attribute, if set, tells Graphviz to print the wolffd@0: graph as an array of pages of the given size. Thus, the graph wolffd@0:

wolffd@0: digraph G {
wolffd@0:   page="8.5,11";
wolffd@0:   ...
wolffd@0: }
wolffd@0: 
wolffd@0: will be emitted as 8.5 by 11 inch pages. When printed, the wolffd@0: pages can be tiled to make a drawing of the entire graph. wolffd@0: At present, the feature only works with PostScript output. wolffd@0:

wolffd@0: Alternatively, there are various tools and viewers which will take wolffd@0: a large picture and allow you to extract page-size pieces, which can wolffd@0: then be printed. wolffd@0:

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

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

wolffd@0: wolffd@0: Q16. How can I get custom shapes or images in my graph? wolffd@0: wolffd@0:

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

wolffd@0: wolffd@0: Q. Sometimes in dotty, right mouse click shows the global menu wolffd@0: but none of the items can be selected. wolffd@0: wolffd@0:

wolffd@0: Check that the NUMLOCK key is off. It's a wolffd@0: wolffd@0: known bug. wolffd@0:

wolffd@0: wolffd@0: Q18. Why does dotty report a syntax error on a legal dot file? wolffd@0: wolffd@0:

wolffd@0: Typically this error is reported as: wolffd@0:

wolffd@0: >> graph parser: syntax error near line 14
wolffd@0: >> context:  >>>  <<< digraph G {
wolffd@0: >> dotty.lefty: giving up on dot
wolffd@0: >> dotty.lefty: graph that causes dot
wolffd@0: >> dotty.lefty: to fail has been saved in file dottybug.dot
wolffd@0: 
wolffd@0: Probably there is a command in your shell environment (such as wolffd@0: .alias or .profile) that does output even for non-interactive shells. wolffd@0: When this occurs, those characters go in the pipe to the dot parser wolffd@0: and cause this problem. An easy check is whether other users have wolffd@0: the same problem. wolffd@0:

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

wolffd@0: Dotty has not really changed for many years. Therefore, there are wolffd@0: myriad features available in Graphviz which it cannot handle. wolffd@0: In some cases, you can use wolffd@0: Grappa wolffd@0: or webdot wolffd@0: for display instead of dotty. wolffd@0: For example, Grappa has generalized polygons wolffd@0: (node [shape=polygon]) that dotty lacks. wolffd@0: There are additional interactive viewers available. For example, see wolffd@0: Graphical Interfaces wolffd@0: and Viewers. If you wolffd@0: are using Mac OS X, the Mac wolffd@0: version of Graphviz has a highly recommended GUI. wolffd@0:

wolffd@0: If the display attribute that you need isn't there already, in dotty, wolffd@0: there's probably no easy way to do it except by rolling up wolffd@0: your sleeves and hacking the dotty code (a lefty script) that wolffd@0: interprets and renders graphical attributes. This is problematic wolffd@0: for the same reason as above: there's no universal low-level driver wolffd@0: layer shared across all the Graphviz tools. We recently added an wolffd@0: intermediate rendering language to the layout tools, but the wolffd@0: various front ends don't use it yet. This would be a good project wolffd@0: for someone who wants to get involved here (along with porting wolffd@0: dotty to GTK.) wolffd@0:

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

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

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

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

wolffd@0: neato -s -n2 -Tgif file.dot -o file.gif
wolffd@0: 
wolffd@0: Note that if an edge does not have a pos attribute wolffd@0: defined, neato will perform whatever edge routing it would wolffd@0: normally do. All of the usual backend attributes (size, wolffd@0: overlap, page, etc.) are available. wolffd@0:

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

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

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

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

wolffd@0: Just run dotty on it. Dotty will use the given pos attributes. wolffd@0:

wolffd@0: wolffd@0: Q25. Same as above, but I have only node coords, not edges. wolffd@0: wolffd@0:

wolffd@0: neato -n is some help, but neato doesn't handle wolffd@0: spline-based parallel edges. wolffd@0:

wolffd@0: wolffd@0: Q26. How can I make client-side image maps? wolffd@0: wolffd@0:

wolffd@0: Use the -Tcmap command line option (only version 1.8.9 and beyond!) wolffd@0:

wolffd@0: wolffd@0: Q27. Why aren't my server-side maps being recognized? I've checked the HTML! wolffd@0: wolffd@0:

wolffd@0: Make sure that your server has map files enabled. For example, if running wolffd@0: apache, check that httpd.conf has a line like the following: wolffd@0:

wolffd@0: AddHandler imap-file map
wolffd@0: 
wolffd@0: and that it is not commented out! wolffd@0:

wolffd@0: wolffd@0: Q. I've installed Debian Graphviz and it works just fine on the command line, wolffd@0: but when I execute a Perl/CGI script through Apache, no output is generated. wolffd@0: For example, the code wolffd@0: wolffd@0: system("/usr/local/bin/dot -Tpng /tmp/tree.dot -o /tmp/tree.png"); wolffd@0: wolffd@0: produces no file /tmp/tree.png. wolffd@0:

wolffd@0: As best as we can tell, dot dies with no stdout or stderr messages on Debian wolffd@0: systems when run from an Apache cgi program wolffd@0: with no HOME set. The workaround is to provide a HOME directory in the wolffd@0: Apache userid's environment. wolffd@0:

wolffd@0: Someone has also suggested using the wolffd@0: wolffd@0: Perl module for Graphviz. wolffd@0:

wolffd@0: wolffd@0: Q29. How can I get 3D output? wolffd@0: wolffd@0:

wolffd@0: The Graphviz authors have qualms about the gratuitous use of 3D. wolffd@0:

wolffd@0: Nonetheless, dot -Tvrml generates VRML files. There's no Z coordinate wolffd@0: layout - you specify Z coords yourself in the z attribute of nodes, wolffd@0: and the Z coordinates of edges are interpolated. If someone wolffd@0: contributes a driver for a newer, more useful format (OpenGL Performer wolffd@0: scene graphs? Open Scene Graphs? Java3D programs?) we'd like to try it. wolffd@0:

wolffd@0: neato internally supports layouts in higher dimensions through the dim wolffd@0: attribute, e.g. neato -Gdim=7 but there's no way to get the output wolffd@0: unless you invoke neato as a library and inspect ND_pos(n)[i] wolffd@0: where n is a pointer to the relevant node. wolffd@0: This would need some (minor) driver work and a good 7-dimensional viewer. Well, wolffd@0: dim=3 ought to be possible. wolffd@0: wolffd@0:

Problems

wolffd@0: wolffd@0: Q30. How can I avoid node overlaps in neato? wolffd@0: wolffd@0:

wolffd@0: Use the graph attribute overlap. wolffd@0:

wolffd@0: wolffd@0: Q31. How can I avoid node-edge overlaps in neato? wolffd@0: wolffd@0:

wolffd@0: Use the overlap attribute to leave room among the nodes, then wolffd@0: use -Gsplines=true. wolffd@0:

wolffd@0: neato -Goverlap=... -Gsplines=true -Gsep=.1
wolffd@0: 
wolffd@0:

wolffd@0: The sep argument is the node-edge separation as wolffd@0: a ratio of a node's bounding box. That is, sep=.1 means wolffd@0: each node is treated as though it is 1.1 times larger than it is. wolffd@0: The actual value may require some tinkering. wolffd@0: (Don't ask why this isn't just a constant!) Note that this option really wolffd@0: slows down neato, so should be used sparingly and only wolffd@0: with modest-sized graphs. wolffd@0:

wolffd@0: wolffd@0: Q32. Neato runs forever on a certain example. wolffd@0: wolffd@0:

wolffd@0: First, how big is your graph? Neato is a quadratic algorithm, roughly wolffd@0: equivalent to statistical multidimensional scaling. If you wolffd@0: feed it a graph with thousands of nodes and edges, it can easily take wolffd@0: hours or days. The first thing to check is to run neato -v to wolffd@0: get a trace of the output. If the numbers you see are generally wolffd@0: getting smaller, the layout is just taking a long time. You can set wolffd@0: certain parameters, such as epsilon or maxiter to wolffd@0: shorten the layout time, at the expense of layout quality. But if your wolffd@0: graph is big, who's going to notice? wolffd@0:

wolffd@0: If you see wolffd@0: the numbers repeating, or fluctuating up and down, then neato is wolffd@0: cycling, especially if your graph is small. wolffd@0: This should never happen by default for versions later than 1.13. If it wolffd@0: does, please report it as a bug. wolffd@0:

wolffd@0: If you are using an earlier version of neato, or you used mode=KK, wolffd@0: cycling is indeed possible. This cycling is very sensitive to the wolffd@0: initial layout. By using the start attribute, for example, wolffd@0:

wolffd@0: neato -Gstart=3
wolffd@0: neato -Gstart=rand
wolffd@0: 
wolffd@0: the cycling will most likely disappear. Or you can employ the parameters used wolffd@0: for large graphs to stop the layout earlier: wolffd@0:
wolffd@0: neato -Gepsilon=.01
wolffd@0: neato -Gmaxiter=500
wolffd@0: 
wolffd@0:

wolffd@0: Note that, if you have a large graph, the generation of edges as splines wolffd@0: is a cubic algorithm, so you would do well to avoid using splines=true. wolffd@0: (This commment applies to circo, fdp and twopi as well.) wolffd@0:

wolffd@0: wolffd@0: Q33. Edge label placement in neato is bad. wolffd@0: wolffd@0:

wolffd@0: Difficult problem. We're working on it. wolffd@0: If anyone has some general wolffd@0: label placement code (e.g. a simulated annealer based on the Marks et al. wolffd@0: technique in Graphics Gems IV), please get in touch. wolffd@0:

wolffd@0: wolffd@0: Q34. Dot runs forever on a certain example. wolffd@0: wolffd@0:

wolffd@0: Try dot -v to observe its progress. wolffd@0:

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

wolffd@0: digraph G {
wolffd@0:     a -> b -> c -> .... -> x -> y -> z
wolffd@0:     a -> z
wolffd@0:     b -> z
wolffd@0:     c -> z
wolffd@0:     /* and so on... */
wolffd@0: 	x -> z
wolffd@0: }
wolffd@0: 
wolffd@0: wolffd@0: The total edge length (therefore the layout time) of wolffd@0: this as a ranked graph is quadratic in the number of nodes. wolffd@0: wolffd@0: wolffd@0: You probably won't encounter the following, but it is also possible wolffd@0: to construct graphs whose parsing takes quadratic time in the number wolffd@0: of attributes, by appending attributes to nodes and edges after the wolffd@0: graph has been loaded. For example: wolffd@0: wolffd@0:
wolffd@0: digraph G {
wolffd@0:     /* really big graph goes here...with N+1 nodes */
wolffd@0:     n0 -> n1 -> ... -> nN;
wolffd@0: 
wolffd@0:     n0 [attr0="whatever",
wolffd@0:         attr1="something else",
wolffd@0:     /* and so on with many more attributes */
wolffd@0:         attrM="something again"]
wolffd@0: }
wolffd@0: 
wolffd@0: When an attribute first appears, each object is visited with possible cost wolffd@0: proportional to the number of previously declared attributes. Thus, wolffd@0: the running time for the above would be cN O(M) wolffd@0: for some constant c. If there is any concern about this, the wolffd@0: graph should specify the attributes first before declaring nodes or wolffd@0: edges. In practice, this problem is neglible. wolffd@0:

wolffd@0: wolffd@0: Q. Twopi runs forever on a certain example. wolffd@0: wolffd@0:

wolffd@0: Is your graph is large (many thousands of edges), wolffd@0: and did you set

splines=true
? It takes wolffd@0: a lot of cycles to fit all those splines! wolffd@0:

wolffd@0: wolffd@0: Q. Neato has unnecessary edge crossings, or has missed an wolffd@0: obvious chance to make a much nicer layout. wolffd@0: wolffd@0:

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

wolffd@0: neato -Gstart=5 file.dot -Tps -o file.ps
wolffd@0: neato -Gepsilon=.0000001 file.dot -Tps -o file.ps
wolffd@0: 
wolffd@0:

wolffd@0: In particular, note that there are no guarantees that neato will produce wolffd@0: a planar layout of a planar graph, or expose all or most of a graph's wolffd@0: symmetries. wolffd@0:

wolffd@0: wolffd@0: Q36. Webdot doesn't work. wolffd@0: wolffd@0:

wolffd@0: We assume you're using Apache and have TCL installed. wolffd@0: If you don't, it's probably better to just use the wolffd@0: wolffd@0: webdot perl script. wolffd@0:

wolffd@0: To debug webdot, first test whether tclsh can load the wolffd@0: Tcldot shared library. Try: wolffd@0:

wolffd@0: $ tclsh
wolffd@0: % load $prefix/lib/graphviz/libtcldot.so.0
wolffd@0: %
wolffd@0: 
wolffd@0: where $prefix is the installation prefix for graphviz; usually /usr wolffd@0: or /usr/local. wolffd@0:

wolffd@0: Then test whether webdot runs from a shell command. (With webdot we provide wolffd@0: a helper script scaffold.tcl or scaffold.sh that sets up an environment wolffd@0: like the one Apache provides.) For example wolffd@0:

wolffd@0: $ scaffold.tcl >out.gif
wolffd@0: can't read "LIBTCLDOT": no such variable
wolffd@0:     while executing
wolffd@0: "file mtime $LIBTCLDOT"
wolffd@0:     invoked from within
wolffd@0: "set t1 [file mtime $LIBTCLDOT]"
wolffd@0:     (file "cgi-bin/webdot" line 67)
wolffd@0:     invoked from within
wolffd@0: "source cgi-bin/webdot
wolffd@0: "
wolffd@0:     (file "scaffold.tcl" line 22)
wolffd@0: 
wolffd@0: The above is a strong clue that webdot is not configured properly. wolffd@0:

wolffd@0: Finally, test whether webdot runs as a cgi-bin program. wolffd@0: It may help to examine the cgi-bin environment using a wolffd@0: simple cgi-bin tcl script like: wolffd@0:

wolffd@0: 	#!/bin/env tclsh
wolffd@0: 	puts "Content-type: text/plain"
wolffd@0: 	puts ""
wolffd@0: 	foreach e [lsort [array names env]] {puts "$e: $env($e)"}
wolffd@0: 
wolffd@0: Save this script as .../cgi-bin/test.tcl, make it executable, then wolffd@0: look at: http://localhost/cgi-bin/test.tcl wolffd@0:

wolffd@0: Also, if you see something like: wolffd@0:

wolffd@0: WebDot Error:
wolffd@0: 
wolffd@0: Response Code = 403
wolffd@0: 
wolffd@0: This usually means that webdot ran succesfully, but was not able wolffd@0: to fetch the remote graph from the URL you gave as an argument. wolffd@0: The reason is probably that your server is behind a firewall that wolffd@0: blocks the webdot server, so it cannot get the graph file. wolffd@0: You can either change firewall permissions, put the graph on a wolffd@0: different server, or install webdot locally so you don't need a wolffd@0: remote server to fetch your graph data. wolffd@0:

wolffd@0: It would be nice if someone hacked webdot to take the contents wolffd@0: of a graph as a cgi-bin argument, so it wouldn't need wolffd@0: permission to fetch a graph remotely. wolffd@0: This is left as an exercise for the Open Source Community. wolffd@0:

wolffd@0: wolffd@0: Q37. I have "Font not found" errors, or text labels missing in webdot. wolffd@0: wolffd@0:

wolffd@0: Firstly, recent versions of graphviz will use fontconfig if it is available wolffd@0: on your platform. With fontconfig, this error should not occur, so you wolffd@0: may want to see if an upgrade to graphviz is available, or if a rebuild wolffd@0: will add fontconfig support. wolffd@0:

wolffd@0: If fontconfig is not available then graphviz tries to resolve fontnames wolffd@0: to fontpaths itself, and uses DOTFONTPATH (or GDFONTPATH) to indicate where it should look. wolffd@0:

wolffd@0: For copyright reasons, Graphviz doesn't come with its own fonts. wolffd@0: On a Windows machine, it knows to search in C:\Windows\Fonts. wolffd@0: On a Unix machine, you need to set up a directory that contains wolffd@0: Truetype fonts. You can get a copy of some fonts wolffd@0: here. wolffd@0:

wolffd@0: The default DOTFONTPATH is: wolffd@0:

wolffd@0: #define DEFAULT_FONTPATH "/usr/X11R6/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/truetype:/usr/X11R6/lib/X11/fonts/TTF:/usr/share/fonts/TrueType:/usr/share/fonts/truetype:/usr/openwin/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/Type1"
wolffd@0: 
wolffd@0: If your fonts are somewhere else, then you must set that directory in wolffd@0: the webdot script, or recompile Graphviz with the correct DEFAULT_FONTPATH wolffd@0: (or set fontpath="/your/font/directory" in every graph you lay out, wolffd@0: but that's pretty clumsy.) wolffd@0:

wolffd@0: wolffd@0: Q38. My browser doesn't recognize SVG. wolffd@0: wolffd@0:

wolffd@0: The correct MIME type for svg images is: image/svg+xml (note "+" not "-"). wolffd@0:

wolffd@0: SVG is not built into all browsers; you can get wolffd@0: plugins wolffd@0: from Adobe for Windows, Linux and some other operating systems. wolffd@0: wolffd@0: Firefox 1.5 has a large subset of SVG and renders graphviz -Tsvg output wolffd@0: though until graphviz 2.8, the fonts may be too large (thanks for wolffd@0: Phil Colbourne at the RailCorp of New South Wales for this advice). wolffd@0:

wolffd@0: For help with embedding SVG in HTML pages, see wolffd@0: here. wolffd@0:

wolffd@0: There are several good standalone viewers and editors for SVG. wolffd@0: We like inkscape. wolffd@0: evince wolffd@0: is the standard Gnome document viewer that handles SVG, at least wolffd@0: since version 0.5 (though Phil C. reports output is blurred) wolffd@0: (see also eog (Eye of Gnome)). wolffd@0: Commercial tools like Adobe Illustrator and Microsoft Visio wolffd@0: can import SVG (the better to deal with your content, my dear!) wolffd@0: If you are using an older (less bloated) Unix system, you wolffd@0: may find tools like Batik wolffd@0: (an SVG renderer in Java) or sodipodi wolffd@0: useful, though it seems they are no longer very actively maintained. wolffd@0: sodipodi is faster but both make sharp images - isn't that the wolffd@0: beauty of path-based graphics? wolffd@0:

wolffd@0: wolffd@0: Q39. libexpat is reported as containing a virus or as a security hole. wolffd@0: Is this a real problem? wolffd@0: wolffd@0:

wolffd@0: No, this is a false positive reported by various security software. wolffd@0: See http://www.pcreview.co.uk/forums/thread-1689630.php or wolffd@0: http://spywareblog.com/index.php/2004/11/24/is_libexpat_dll_spyware. wolffd@0:

wolffd@0: wolffd@0: Q40. What is the coordinate transformation between the graph bb and a .png image? wolffd@0:

    wolffd@0:
  1. wolffd@0: The bb is expanded by 4 graph-units in all directions (pad) to allow for finite line widths. wolffd@0:
  2. wolffd@0: Then it is zoomed and/or rotated according to -Gviewport, -Gsize, -Glandscape, -Gorientation options. wolffd@0: At the default scaling of 1:1, one graph unit = 1 point (1/72 inch). wolffd@0:
  3. wolffd@0: Then it is paginated, if requested by -Gpage and if the output format supports it. Not the -Tpng renderer, yet. wolffd@0:
  4. wolffd@0: Then a margin is added, -Gmargin, in absolute units (inches). wolffd@0: The top/bottom margin can be set independently of the left/right margin. wolffd@0:
  5. wolffd@0: Then it is converted to device units, according to -Gdpi, wolffd@0: or a dpi value that is given by the output device, wolffd@0: or a default that is provided by each render. wolffd@0: There are separate dpi values for x and y to allow for non-square pixels. wolffd@0: Some renderers invert the Y axis and need an offset to place the wolffd@0: origin in the top left corner. wolffd@0: The default dpi for -Tpng is 96dpi (approximating the resolution wolffd@0: of most computer monitors) so this is where the scaling by 96/72 (4/3) wolffd@0: comes from. wolffd@0:
wolffd@0:

wolffd@0: At the renderer api, plugins have a choice of coordinate representation: wolffd@0:

wolffd@0:

wolffd@0: wolffd@0: Q41. File associations are broken in Mac OSX. Clicking on a dot file doesn't open Graphviz. wolffd@0:

wolffd@0: The immediate fix is to rebuild the Launch Services database like this: wolffd@0:

wolffd@0: 1. Trash all other versions of Graphviz.app on your system, except for the just installed one. You can use either of these command lines to find it: wolffd@0:

wolffd@0:

locate Graphviz.app
wolffd@0:

wolffd@0: or wolffd@0:

wolffd@0:

find / -name "Graphviz.app"
wolffd@0:

wolffd@0: 2. Run the following command line: wolffd@0:

wolffd@0:

/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -r / 
wolffd@0:

wolffd@0: or wolffd@0:

wolffd@0:

/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -r /Applications
wolffd@0:

wolffd@0: which deletes the Launch Services database and rebuilds it from existing apps. You may need to sudo to do this. wolffd@0:

wolffd@0: 3. Verify that the Graphviz.app can now open .dot files and Microsoft Word can still open its own .dot files. wolffd@0:

wolffd@0: One artifact of this will be that Microsoft .dot files may appear with the Graphviz document icon. Unfortunately there doesn't seem any a priori way of getting the system to determine whether an arbitrary .dot file belongs to Word or Graphviz -- you can choose which application to open with by right-clicking or control-clicking on the document icon and choosing the app. wolffd@0:

wolffd@0: As for why the Launch Services database doesn't automatically register Graphviz, wolffd@0: we're not entirely sure but suspect this only happens if both conditions wolffd@0: hold true: wolffd@0:

wolffd@0: A. The user had installed Microsoft Word.
wolffd@0: B. There is also another version of Graphviz.app present in the system. (Possibly the previous version 1.13 released by Pixelglow Software)
wolffd@0: Q41. What do all these plugin libraries do? wolffd@0:

wolffd@0:

wolffd@0: wolffd@0: wolffd@0: wolffd@0: