Graphviz
Graphviz is open source graph visualization software. Graph visualization is a way of representing structural information as diagrams of abstract graphs and networks. It has important applications in networking, bioinformatics, software engineering, database and web design, machine learning, and in visual interfaces for other technical domains.
Starting in the middle of
- cover graph of the Aesthetic Programming book: https://aesthetic-programming.net/ (OSP, Winnie Soon, Geoff Cox)
- OSP workshop at Karlsruhe with etherdot: http://osp.kitchen/workshop/karlsruhe/ (June 2023)
- So-and-sovereignty diagrams (Martino Morandi and Femke Snelting/TITiPI) + https://gitlab.constantvzw.org/titipi/Tardigraph, source: https://gtr.ukri.org/projects?ref=AH%2FX006379%2F1
- The Art of Asking Your Boss, by George Perec; described in Mainframe Experimentalism, by Hannah Higgins Chapter 2
what Perec discovered as he wrote out the “simultaneous” flowchart protocol was that time reinserts itself by necessity in any narrative, even when obstinately restricted to the present tense: the employee seeking a raise is a little older at each approach to his head of department whenever the arrows and choices take him back to the top of his chart. Because of this, the recursion cannot be infinite, because if algorithms exist without time, men do not, and must die. – Mainframe Experimentalism, by Hannah Higgins
- graphviz gallery https://graphviz.org/gallery/
- gradient examples https://graphviz.org/Gallery/gradient/
- dot-to-ascii web editor: https://dot-to-ascii.ggerganov.com/
- PythonGraphviz
Nodes and edges
Graphviz works with the dot language, based on nodes and edges. You can change the type, color and behavior of these with attributes and shapes:
This page lists a range of examples: https://renenyffenegger.ch/notes/tools/Graphviz/examples/index
Layout engines
Graphviz comes with a set of different built-in layout engines and each of these render the graph differently:
- dot: hierarchical
- neato: spring
- circo: circular
- twopi: radial
- fdp: force-directed placement
Each of these are installed when you install graphviz. To use them, you change use the name of the layout engine as command in the CLI:
$ dot hello.dot -Tsvg -ofile hello.svg $ neato hello.dot -Tsvg -ofile hello.svg $ circo hello.dot -Tsvg -ofile hello.svg $ twopi hello.dot -Tsvg -ofile hello.svg $ fdp hello.dot -Tsvg -ofile hello.svg
You can check them all here: https://graphviz.org/docs/layouts/
Output formats
Graphviz uses a range of output formats, such as:
- svg
- png
- jpeg
To change the output format, you change the -Tsvg
part of your command:
$ dot hello.dot -Tsvg -ofile hello.svg $ dot hello.dot -Tpng -ofile hello.svg $ dot hello.dot -Tjpg -ofile hello.svg $ dot hello.dot -Tpdf -ofile hello.svg
There is a list here: https://graphviz.org/docs/outputs/
What is nice when you export to svg is that you can use graphviz as an initial step in your workflow, and continue working on your diagram in other vector editing software, such as Inkscape or others. And! when saving as svg, your diagram stays a vector drawing, which also means you scale it, copy/paste it into a web page, and... pen plot it!
And about png: this is a good image file format if you want to render your diagram as a static image file, as it good for detailed line drawings and typography, and it support transparency.
dot language
Some examples.
You create edges with an "arrow": ->
:
digraph {
hello -> xpub
}
You can use id's to assign attributes to a node:
digraph {
A [label="Hello" shape=diamond]
B [label="XPUB" shape=box]
C [label="1" shape=circle]
A -> B
A -> C
A -> D
}
You can use subgraphs to create multiple edges in one go:
digraph {
hello -> {XPUB1 XPUB2}
}
And you can use attributes to render your diagram in a specific way/color/font/size/...:
digraph {
/* set graph attributes here */
bgcolor="yellow:pink"
gradientangle=90
/* set node attributes here */
A [label="hello" style=filled color=blue fillcolor="lightgreen:lightyellow" gradientangle=0]
B [label="xpub" style=filled]
/* set edge attributes here */
A -> B [color=purple]
}