Render DOT script with multiple graphs to PDF one graph per page

11.9k views Asked by At

I have a large DOT script with multiple graphs defined in it:

digraph Tree0 {
  ...
}

digraph Tree1 {
  ...
{
...

I can render this to a postscript file where each graph is on a separate page by calling dot -Tps forest.dot -o forest.ps. However, for performance reasons I would prefer PDF over postscript (scrolling and zooming is much smoother). But if I use the same command with PDF instead of PS, the resulting file contains only one of the graphs and it looks like the rest is written to stdout.

Converting the PS to PDF with ps2pdf did not work, as the graphs and thus the pages of the PS file have varying size but the resulting PDF file will have fixed page size, cutting away parts of the graphs.

Is there an easy way to get a multi-graph PDF from dot, like it works with the PS file? If not, how can I convert the PS to PDF and keep the varying page size?

4

There are 4 answers

1
Augustin On BEST ANSWER

What about this: dot -Tps2 forest.gv -o forest.ps | ps2pdf forest.ps

The main difference is it uses -Tps2. According to documentation:

ps2 Produces PostScript output with PDF notations. It is assumed the output will be directly converted into PDF format. The notations include PDF bounding box information, so that the resulting PDF file can be correctly used with pdf tools, such as pdflatex. In addition, if a node has a URL attribute, this gets translated into PDF code such that the node, when viewed in a PDF-viewer, e.g., acroread, is a link to the given URL. If a URL is attached to the graph, this serves as a base, such that relative URLs on nodes are derived from it.

1
luator On

I just found an solution myself, using csplit and pdftk:

dot -Tpdf forest.dot | csplit --quiet --elide-empty-files --prefix=tmpforestfile - "/%%EOF/+1" "{*}" && pdftk tmpforestfile* cat output forest.pdf && rm -f tmpforestfile*
  1. dot writes all the separate pdf files in one single output
  2. pipe this output to csplit and split it to separate files, using the %%EOF token
  3. concatenate the pdf files to one, using pdftk
  4. remove the temporary files

A bit ugly but it is working.

0
Michael D. Adams On

(1) It seems GraphViz has changed how drivers are named, so -Tps2 (from the answer by @Augustin) does not work for me. However, -Tps:cairo:cairo does work. (One can get a list of ps drivers with dot -Tps:.)

(2) One can directly pipe the output of dot to ps2pdf without the intermediate forest.ps file by passing - to ps2pdf.

These two result in the following command, which works for me.

dot -Tps:cairo:cairo forest.gv | ps2pdf - >forest.pdf
0
Michail Alexakis On

I had a similar problem having multiple graphs to be exported as a single image (PNG or SVG or...). Using PS/PS2 output and converting to PDF was not satisfactory because it sometimes misplaced component images (or cropped them) and also had no easy way of viewing the result as a whole.

I ended up using imagick to simple glue component PNG images side-by-side.

This is a simple solution: https://gist.github.com/drmalex07/1088544cfc121acab0463691f71fef0a