How to use Graphviz to align nodes circular in clusters with additional text? Optionally with identical node positions (always 8 nodes per cluster)?
I tried circo, however, faced some shortcomings:
No clustering
No comments
Problems with margins for larger labels (10+ char)
Alignment varies with label size
This (Graphviz Online), nothing spectacular, was the closest I could get. Any hints to other layouts (or even tools) appreciated.
graph {
layout = circo;
node [shape = circle,
fontname = Helvetica,
margin = 0]
edge [style=invis]
subgraph 1 {
a1 -- b1 -- c1 -- d1 -- e1 -- f1 -- g1 -- h1 -- a1
}
subgraph 2 {
a -- b -- c -- d -- e -- f -- g -- h -- a
}
}
Not exactly the answer as I was asking for (Graphviz), but I found a much nicer solution with MATLAB. It was about plotting a seating plan for an event.
What I did broken down:
imread() image of the floor plan
Roughly determined pixel spacing, used as x & y vector for image() so that tables are in scale with the room.
Manually defined centers for the clusters (here tables) with the help of ginput() (or imellipse())
Plotted circles with plot() and added text with text()
Related
I would like to create a spline curve between the blue point and the green point with the red point as a control point.
Graphviz documentation says :
splines attribute, of type bool or string, is valid on Graphs
splineType with the pattern : spline ( ';' spline )* is a valid type for pos attribute
pos attribute is valid on Edges and Nodes
I Tried this graph
graph G{
layout ="neato" outputorder="edgesfirst" splines="true"
a[shape="point" pos="0,0!" color="blue"]
b[shape="point" pos="1,0!" color="green"]
c[shape="point" pos=" 0.5,0.5!" color="red"]
a -- b [pos="e,1,0 s,0,0 0.5,0.5!"]
}
then on Windows 10 PowerShell :
neato.exe -Tsvg .\spline.dot > .\spline.svg
with
neato - graphviz version 2.49.3 (20211023.0002)
result
What is the proper way of achieving this?
Thanks.
Close, but ...
! notation seems to only apply to nodes (not edges) (poorly documented, but see: https://graphviz.org/docs/attr-types/point/ and https://graphviz.org/docs/attrs/pin/)
by default, pos value units are points (inch/72). Your values are ~ too small
neato -n2 will use node & edge values you provide (https://graphviz.org/faq/#FaqDotWithCoords)
all edges (not just curves) are defined as cubic B-splines and are defined by 1 + n*3 points (n is integer >=1) (https://graphviz.org/docs/attr-types/splineType/) (i.e. 4 or 7 or 11 or ...)
So:
graph G{
// default units for pos values are in points (72/inch)
// multiplied by 100 out of laziness
// ! only applies to nodes, not edges
layout ="neato"
outputorder="edgesfirst" // why???
splines="true"
a[shape="point" pos="0,0!" color="blue"]
b[shape="point" pos="100,0!" color="green"]
c[shape="point" pos="50,50!" color="red"]
// "s" arrowhead must preceed "e" arrowhead, so swaped them
// BUT, "--" says non-directed graph, NO arrowheads, so they are deleted
// also need 4, 7, 11, ... points NOT including arrowhead points
// so added points (just guesses)
a -- b [pos="0,0 30,66 70,66 100,0"]
}
Gives:
Whew
I'm trying to make basic polygons with graphviz. I have something like this:
graph {
node [shape=circle]
A [pos="0,1!"]
B [pos="0,0!"]
C [pos="1,0!"]
D [pos="1,1!"]
A -- B
B -- C
C -- D
D -- A
}
which displays the following
I'd like the circles to disappear and look more like this:
I tried switching to shape=point, but the labels disappear. Any suggestions?
When using shape=point, adding a xlabel to each node will display a label outside of the node shape:
A [pos="0,1!", xlabel="A"]
The documentation states that the label will be placed outside the node shape, but near the node itself. However, those labels are placed last and can sometimes be omitted (forcelabels to the rescue).
The position or an offset can not be defined.
I have a simple vertical graph that looks nice and symmetrical without any labels using the following code:
digraph test_alignment
{
{rank=same; a -> b;}
a -> c;
b -> c;
c -> d;
d -> e;
d -> f;
{rank=same; e -> f;}
}
I'd like to label the edge between A and B as well as the one between E and F, using the same string for each label. I'm expecting the same output, except with longer A->B and E->F edges bearing the same label.
Unfortunately, as soon as I add a label to one of these edges, the general layout looks slightly askew (the result is similar if I add a label to the E->F edge):
digraph test_alignment
{
{rank=same; a -> b [label="Label"];}
a -> c;
b -> c;
c -> d;
d -> e;
d -> f;
{rank=same; e -> f;}
}
I'm very new to graphviz and, following many questions on Stack Overflow, I have been experimenting with different combinations of rank and constraint, I tried using clusters to see if it would keep the top and bottom part properly aligned independently, and tried using a mix of dot, ccomp, gvpack and neato that produced similar results.
It always seems to boil down to the fact adding a label to the edge between nodes with the same rank affects how these nodes are positioned in a way I don't yet understand.
Am I missing something trivial, or am I attempting something I shouldn't instead of letting dot do its thing?
I'm using dot - graphviz version 2.36.0 (20140111.2315) and the linked pictures were produced with dot only (though I obtained similar results when using :
dot test_alignment.dot -Tpng -O
You may try to use the xlabel attribute, together with forcelabels if necessary. From the description:
... For edges, the label will be placed near the center of the edge. This
can be useful in dot to avoid the occasional problem when the use of
edge labels distorts the layout. ...
How to label the edges in an image, I have some of the cells that I have applied edge detection techniques. Now I want to label the edge detected cell from an image.
You'll need to give more information: how well does the edge detection work? Do you get whole blobs, or disconnected, but related, edges? Posting an example of the sort of image, and the problem would be good --- pictures (images) are worth a thousand words, particularly when describing image processing problems.
This page might be a start. It gives the pseudocode:
l = 1 // Initial Label number
for each pixel
if pixel X is foreground
if neighbours A,B,C & D are unlabelled (equal to zero)
label pixel X with l
increment l
else
num = neighbour label A,B,C & D with least value, not including 0
label pixel X and pixels A, B, C & D if foreground with num
end if
end if
done
How do I configure the distance between edges and nodes (red), i.e. the outer shape of a node(blue)?
Here is a technique that you can consider that avoids the need to create a custom node shape. There may be some matters of taste that you may need to address further in order to get exactly what you want.
The advantage of this technique, using HTML-like labels, is that varying the space inside and outside the rectangle becomes a simple matter of changing the inner number of points (here 4) and outer number of points (here 16) respectively.
digraph {
node [shape=none]
O [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="16" CELLPADDING="4">
<TR><TD WIDTH="70">\N</TD></TR>
</TABLE>
>]
{a,b,c,d} -> O
}
Result:
You can change the BORDER and CELLBORDER parameters to show or hide the rectangles. You can adjust their thicknesses although only in multiples of 1 point. I have used the WIDTH parameter to force a width-to-height ratio that causes the aligning of all the arrow tips. Otherwise some of the tips would meet the sides of the invisible outer rectangle.
Like the other answer said, this isn't really an easy feat. Using a combination of height, width, fixedsize, labelloc, and margin node parameters, you can probably get any desired effect you'd like. Margin is best is you're looking to expand that distance, but to minimize it you need to use the other params. For example, this graph would have the arrowheads almost touching the 'O' node's text.
digraph {
node [shape="none" width=.2 height=.2 fixedsize="true" labelloc="top"];
a -> O;
b -> O;
c -> O;
d -> O;
}
Alternatively, if you really want to put in effort, you could create a custom node shape, and do whatever you'd like to it.
This is not possible AFAIK.
The only option available is using headclip to have the edge go to the center of the node or to the edge of the outer shape (as you did in your example).
You may try to add some padding to a node by putting it in a cluster and have the edges clip at the (invisible) border of the cluster:
digraph {
compound=true;
subgraph cluster1 {
style=invis;
2;
}
1 -> 2[lhead=cluster1];
}
Hopefully somebody knows a better hack for this...