Using Graphviz to create a graph of interconnected circles - graphviz

I want to use Graphviz to create a graph of multiple centred circular layouts, similar to those created by the old "they rule" app online.
With this sample input:
graph G {
"Group 1" -- { "Bob" "Andy" "Chris" "George" "Herbert" "Fred" }
"Group 2" -- { "Bob" "Diana" "Egbert" "Fred" "George" "Ian" }
"Group 3" -- { "Diana" "Ian" "Chris" "Jasper" }
}
circo produces close to the correct output, but creates an unnecessary large empty circle in the middle of the diagram, where three connected layouts would be neater. Both neato and twopi tend to overlap nodes or do not hold the clusters together.
Is there any graphviz option, or a different package, that can use a circo style layout within the clusters then connect the shared nodes in the clusters neato style? I tried using subgraphs in circo or using packMode="clust" but it was still disregarded in favor of fitting everything to a large circle.

Related

Graphviz: Putting a Caption on a Node In Addition to a Label

In my Graphviz graph (written in DOT), I want each node to have a label, but in addition to that, I want some nodes to have a small caption denoting some other unique value for that node. For example, if this were for a history diagram, a node's label might be something like "Birth of George Washington" and the caption might read "See also: American Revolution."
This is fairly flexible, so the caption doesn't necessarily need to be inside the node, but I do need some other way of putting text that clearly isn't part of the label (e.g. is a different size, possibly a different color) and is in a different location but is still clearly a part of the node.
Is there any way to do this?
To place captions outside the node, you may use xlabel:
digraph g {
forcelabels=true;
a [label="Birth of George Washington", xlabel="See also: American Revolution"];
b [label="Main label", xlabel="Additional caption"];
a-> b;
}
forcelabels=true makes sure no xlabel is omitted.
A second option is to use HTML-like labels:
digraph g {
a[label=<Birth of George Washington<BR />
<FONT POINT-SIZE="10">See also: American Revolution</FONT>>];
}

How do you center a title for a diagram output to SVG using dot?

So far I tried this line but dot keeps pushing it aside making room for my nodes (pushes it to the right):
_diagram_info [shape="plaintext", label="My Diagram\l", fontsize=13]
Is there a way to center the label by pos, using dot?
That's how I'd add a title for a graph:
digraph {
// nodes, edges, subgraphs
...
// title
labelloc="t";
label="My Diagram";
}
This will add a centered title to the top of the graph.
The same syntax can also be used for subgraphs.

how can I adjust direction of edge in dot diagram?

Before asking, I tried to search the answer for my question, buf I couldn't find.
My question is about changing edge direction in dot diagram. Rankdir is 'LR', but in certain part of graph, I want to use 'TB'. Let me give an example.
digraph G {
rankdir=LR;
size="7,5";
browser->ui_thread;
browser->db_thread;
browser->webkit_thread;
browser->cache_thread;
browser->file_thread;
browser->io_thread;
io_thread[style=filled];
cache_thread[style=filled];
ui_thread->thread[label=inherit];
ui_thread->messageloop[style=dotted];
db_thread->messageloop[style=dotted];
webkit_thread->messageloop[style=dotted];
cache_thread->messageloop[style=dotted];
file_thread->messageloop[style=dotted];
io_thread->messageloop[style=dotted];
}
it gives out graph like this
But, this is not what I want.
I want the following image. "thread" is above "ui_thread" vertically.
You may think it can be solved easily using "rankdir=same" with "thread" and "ui_thread".
I sure tried this already. but I failed. "thread" is always below "ui_thread".
thanks,
Unfortunately, graph direction can only be specified once, and the whole graph stays in that direction. In this situation, you can usually get the desired effect with a combination of constraint=false and invisible edges to force some ordering.
This code will produce your second image:
digraph G {
rankdir=LR;
size="7,5";
browser->thread[style=invis];
browser->ui_thread;
browser->db_thread;
browser->webkit_thread;
browser->cache_thread;
browser->file_thread;
browser->io_thread;
io_thread[style=filled];
cache_thread[style=filled];
ui_thread->thread[label=inherit constraint=false];
ui_thread->messageloop[style=dotted];
db_thread->messageloop[style=dotted];
webkit_thread->messageloop[style=dotted];
cache_thread->messageloop[style=dotted];
file_thread->messageloop[style=dotted];
io_thread->messageloop[style=dotted];
}

Graphviz (DOT) Captions

I need to print a large number of graphs using Graphviz DOT. To distinguish which input each graph corresponds to, I want to also have a caption for each graph. Is there anyway to embed this into the DOT representation of the graphs.
You can use label to add a caption to the graph.
Example:
digraph {
A -> B;
label="Graph";
labelloc=top;
labeljust=left;
}
labelloc and labeljust can be used to determine top/bottom and left/right position of the graph label.
All the details and other attributes that can be used to modify the label (font etc) in the graphviz attribute reference.
Tip: Define the graph label end of your dot file, otherwise subgraphs will inherit those properties.
Graph's can have attributes just like nodes and edges do:
digraph {
graph [label="The Tale of Two Cities", labelloc=t, fontsize=30];
node [color=blue];
rankdir = LR;
London -> Paris;
Paris -> London;
}
That dot file produces this graph.
If you are looking for a way to add a caption to a Graph object of graphviz in python. Then the following code can help:
from graphviz import Graph
dot = Graph()
dot.node('1','1')
dot.node('2','2')
dot.edge('1','2', label="link")
dot.attr(label="My caption")
dot.attr(fontsize='25')
dot.render(view=True)
Output:

record nodes and rankdir in graphviz

When I changed the rankdir of my graph from LR to TD, my record nodes also changed their layout direction so they no longer look like a 'record'. I tried applying a separate rankdir to the nodes, but this had no effect.
How does one keep the record nodes with the correct layout?
digraph sample {
graph [rankdir=TD];
node [shape=record];
A [label="ShouldBeTop | ShouldBeBottom"];
B [label="Top | Bottom"];
A -> B;
}
Taking into account that rankdir effectively replaces the notion of "top" and "bottom" for the given graph, that's not surprising.
I am afraid that there is no easy remedy for this, save hacking the source (and that would not be easy at all). You can surround your labels in "{}" with some kind of mass search-replace solution to get the requested effect:
digraph sample { graph [rankdir=TD]; node [shape=record];
A [label="{ShouldBeTop | ShouldBeBottom}"];
B [label="{Top | Bottom}"]; A -> B;
}
You can use html table like labels instead of records. IIRC the table based labels do not rotate with the rank direction. See http://www.graphviz.org/doc/info/shapes.html#html

Resources