# Forcefully draw edges on top of each other

**URL:** <https://forum.graphviz.org/t/forcefully-draw-edges-on-top-of-each-other/266>\
**Category:** Uncategorized\
**Created:** [July 20, 2020, 1:21pm UTC](https://forum.graphviz.org/t/forcefully-draw-edges-on-top-of-each-other/266 "2020-07-20T13:21:46Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![snowmb](https://avatars.discourse-cdn.com/v4/letter/s/a183cd/32.png) [@snowmb](https://forum.graphviz.org/u/snowmb)\
**Post date:** [July 20, 2020, 1:21pm UTC](https://forum.graphviz.org/t/forcefully-draw-edges-on-top-of-each-other/266/1 "2020-07-20T13:21:46Z")

</div>

Hello,

I came to working with graphviz over a tool called [wireviz](https://github.com/formatc1702/WireViz). The author uses graphviz to visualize cable connections and wire colors.

To make the resulting graph visually appealing he uses 2 colors (black, wire color, black) on edges. In reality there might also be 2 colored wires which now is solved by using 5 colors on a single edge (black, color1, color2, color1, black).

I would prefer to get a banded look on 2 colored wires, which can be achieved (in a way) by defining color weights but than there is no black border anymore.

```auto
color="#ffffff;0.1:#00ff00;0.1:#ffffff;0.1:#00ff00;0.1:#ffffff;0.1:#00ff00;0.1:#ffffff;0.1:#00ff00;0.1:#ffffff;
0.1:#00ff00;0.1"

```

While playing around with the graph description in the dot language I found a way to get graphviz to draw multiple edges exactly on top of each other, so I can use different `penwidth` and `style` to get a good result but I’m not sure if this behaviour is actually a bug in graphviz.

 ![](https://global.discourse-cdn.com/graphviz/original/1X/0167f067e4d547c588b6f4c0c56c54cc16179bbf.png)

Here the `dot` code.

```auto
graph {
// Graph generated by WireViz
// https://github.com/formatc1702/WireViz
	graph [bgcolor="#ffffff" fontname=arial nodesep=0.33 rankdir=LR ranksep=2]
	
	node [fillcolor=white fontname=arial shape=record style=filled]
	X1 [label=<<table border="0" cellspacing="0" cellpadding="0"><tr><td><table border="0" cellspacing="0" cellpadding="3" cellborder="1"><tr><td balign="left">X1</td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="3" cellborder="1"><tr><td balign="left">Stewart Connector SS-37000-002</td><td balign="left">male</td><td balign="left">8-pin</td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="3" cellborder="1"><tr><td>DA+</td><td port="p1r">1</td></tr><tr><td>DA-</td><td port="p2r">2</td></tr><tr><td>DB+</td><td port="p3r">3</td></tr><tr><td>DC+</td><td port="p4r">4</td></tr><tr><td>DC-</td><td port="p5r">5</td></tr><tr><td>DB-</td><td port="p6r">6</td></tr><tr><td>DD+</td><td port="p7r">7</td></tr><tr><td>DD-</td><td port="p8r">8</td></tr></table></td></tr></table>> fillcolor=white margin=0 shape=none style=filled]
	X2 [label=<<table border="0" cellspacing="0" cellpadding="0"><tr><td><table border="0" cellspacing="0" cellpadding="3" cellborder="1"><tr><td balign="left">X2</td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="3" cellborder="1"><tr><td balign="left">Stewart Connector SS-37000-002</td><td balign="left">male</td><td balign="left">8-pin</td></tr></table></td></tr><tr><td><table border="0" cellspacing="0" cellpadding="3" cellborder="1"><tr><td port="p1l">1</td><td>DB+</td></tr><tr><td port="p2l">2</td><td>DB-</td></tr><tr><td port="p3l">3</td><td>DA+</td></tr><tr><td port="p4l">4</td><td>DD+</td></tr><tr><td port="p5l">5</td><td>DD-</td></tr><tr><td port="p6l">6</td><td>DA-</td></tr><tr><td port="p7l">7</td><td>DC+</td></tr><tr><td port="p8l">8</td><td>DC-</td></tr></table></td></tr></table>> fillcolor=white margin=0 shape=none style=filled]
	W1 [label=<<table border="0" cellspacing="0" cellpadding="0"><tr><td><table border="0" cellspacing="0" cellpadding="3" cellborder="1"><tr><td colspan="4">W1</td></tr><tr><td balign="left">CAT5e</td><td balign="left">8x</td><td balign="left">24 AWG</td><td balign="left">1 m</td></tr></table></td></tr><tr><td>&nbsp;</td></tr><tr><td><table border="0" cellspacing="0" cellborder="0"><tr><td>X1:1</td><td>WHGN</td><td>X2:3</td></tr><tr><td colspan="3" border="0" cellspacing="0" cellpadding="0" port="w1" height="10"><table cellspacing="0" cellborder="0" border = "0"><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#ffffff" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#00ff00" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#ffffff" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr></table></td></tr><tr><td>X1:2</td><td>GN</td><td>X2:6</td></tr><tr><td colspan="3" border="0" cellspacing="0" cellpadding="0" port="w2" height="10"><table cellspacing="0" cellborder="0" border = "0"><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#00ff00" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#00ff00" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#00ff00" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr></table></td></tr><tr><td>X1:3</td><td>WHOG</td><td>X2:1</td></tr><tr><td colspan="3" border="0" cellspacing="0" cellpadding="0" port="w3" height="10"><table cellspacing="0" cellborder="0" border = "0"><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#ffffff" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#ff8000" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#ffffff" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr></table></td></tr><tr><td>X1:4</td><td>BU</td><td>X2:7</td></tr><tr><td colspan="3" border="0" cellspacing="0" cellpadding="0" port="w4" height="10"><table cellspacing="0" cellborder="0" border = "0"><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#0066ff" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#0066ff" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#0066ff" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr></table></td></tr><tr><td>X1:5</td><td>WHBU</td><td>X2:8</td></tr><tr><td colspan="3" border="0" cellspacing="0" cellpadding="0" port="w5" height="10"><table cellspacing="0" cellborder="0" border = "0"><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#ffffff" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#0066ff" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#ffffff" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr></table></td></tr><tr><td>X1:6</td><td>OG</td><td>X2:2</td></tr><tr><td colspan="3" border="0" cellspacing="0" cellpadding="0" port="w6" height="10"><table cellspacing="0" cellborder="0" border = "0"><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#ff8000" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#ff8000" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#ff8000" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr></table></td></tr><tr><td>X1:7</td><td>WHBN</td><td>X2:4</td></tr><tr><td colspan="3" border="0" cellspacing="0" cellpadding="0" port="w7" height="10"><table cellspacing="0" cellborder="0" border = "0"><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#ffffff" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#895956" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#ffffff" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr></table></td></tr><tr><td>X1:8</td><td>BN</td><td>X2:5</td></tr><tr><td colspan="3" border="0" cellspacing="0" cellpadding="0" port="w8" height="10"><table cellspacing="0" cellborder="0" border = "0"><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#895956" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#895956" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#895956" border="0"></td></tr><tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr></table></td></tr><tr><td>&nbsp;</td></tr></table></td></tr></table>> fillcolor=white margin=0 shape=box style=""]
	

	edge [penwidth=10.0 color="#000000"]
	X1:p1r:e -- W1:w1:w
	W1:w1:e -- X2:p3l:w
	edge [style="invis"]
	X1 -- W1
	W1 -- X2
	edge [penwidth=6.0 style="" color="#ffffff;0.1:#00ff00;0.1:#ffffff;0.1:#00ff00;0.1:#ffffff;0.1:#00ff00;0.1:#ffffff;0.1:#00ff00;0.1:#ffffff;0.1:#00ff00;0.1"]
	X1:p1r:e -- W1:w1:w
	W1:w1:e -- X2:p3l:w

	edge [penwidth=10.0 color="#000000"];
	X1:p2r:e -- W1:w2:w
	W1:w2:e -- X2:p6l:w
	edge [style="invis"]
	X1 -- W1
	W1 -- X2
	edge [penwidth=6.0 style="" color="#00ff00"]
	X1:p2r:e -- W1:w2:w
	W1:w2:e -- X2:p6l:w

	edge [penwidth=10.0 color="#000000"];
	X1:p3r:e -- W1:w3:w
	W1:w3:e -- X2:p1l:w
	edge [style="invis"]
	X1 -- W1
	W1 -- X2
	edge [penwidth=6.0 style="" color="#ffffff;0.1:#ff8000;0.1:#ffffff;0.1:#ff8000;0.1:#ffffff;0.1:#ff8000;0.1:#ffffff;0.1:#ff8000;0.1:#ffffff;0.1:#ff8000;0.1"]
	X1:p3r:e -- W1:w3:w
	W1:w3:e -- X2:p1l:w

	edge [penwidth=10.0 color="#000000"];
	X1:p4r:e -- W1:w4:w
	W1:w4:e -- X2:p7l:w
	edge [style="invis"]
	X1 -- W1
	W1 -- X2
	edge [penwidth=6.0 style="" color="#0066ff"]
	X1:p4r:e -- W1:w4:w
	W1:w4:e -- X2:p7l:w

	edge [penwidth=10.0 color="#000000"];
	X1:p5r:e -- W1:w5:w
	W1:w5:e -- X2:p8l:w
	edge [style="invis"]
	X1 -- W1
	W1 -- X2
	edge [penwidth=6.0 style="" color="#ffffff;0.1:#0066ff;0.1:#ffffff;0.1:#0066ff;0.1:#ffffff;0.1:#0066ff;0.1:#ffffff;0.1:#0066ff;0.1:#ffffff;0.1:#0066ff;0.1"]
	X1:p5r:e -- W1:w5:w
	W1:w5:e -- X2:p8l:w

	edge [penwidth=10.0 color="#000000"];
	X1:p6r:e -- W1:w6:w
	W1:w6:e -- X2:p2l:w
	edge [style="invis"]
	X1 -- W1
	W1 -- X2
	edge [penwidth=6.0 style="" color="#ff8000"]
	X1:p6r:e -- W1:w6:w
	W1:w6:e -- X2:p2l:w
	
	edge [penwidth=10.0 color="#000000"];
	X1:p7r:e -- W1:w7:w
	W1:w7:e -- X2:p4l:w
	edge [style="invis"]
	X1 -- W1
	W1 -- X2
	edge [penwidth=6.0 style="" color="#ffffff;0.1:#895956;0.1:#ffffff;0.1:#895956;0.1:#ffffff;0.1:#895956;0.1:#ffffff;0.1:#895956;0.1:#ffffff;0.1:#895956;0.1"]
	X1:p7r:e -- W1:w7:w
	W1:w7:e -- X2:p4l:w

	edge [penwidth=10.0 color="#000000"];
	X1:p8r:e -- W1:w8:w
	W1:w8:e -- X2:p5l:w
	edge [style="invis"]
	X1 -- W1
	W1 -- X2
	edge [penwidth=6.0 style="" color="#895956"]
	X1:p8r:e -- W1:w8:w
	W1:w8:e -- X2:p5l:w
}

```

I’m not sure why this is working so here my question: Is there any way to force graphviz to draw edges on top of each other? Or are there any more sophisticated possibilities to style edges?

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [July 20, 2020, 10:46pm UTC](https://forum.graphviz.org/t/forcefully-draw-edges-on-top-of-each-other/266/2 "2020-07-20T22:46:00Z")

</div>

What specific part(s) of this file are iffy to you?  
Could you provide a simpler graph with one set of edges?

---

<div class="post-metadata">

**Author:** ![snowmb](https://avatars.discourse-cdn.com/v4/letter/s/a183cd/32.png) [@snowmb](https://forum.graphviz.org/u/snowmb)\
**Post date:** [July 21, 2020, 10:25am UTC](https://forum.graphviz.org/t/forcefully-draw-edges-on-top-of-each-other/266/3 "2020-07-21T10:25:13Z")

</div>

Sure here is a minimal example:

![ex10.gv](https://global.discourse-cdn.com/graphviz/original/1X/350a782e9e9df2d985fcc343131bc28ca35ed1d0.png)

```auto
graph {
	A:e -- X:w [penwidth=9.0 color="#000000"]
	//A -- X [color="#ff0000"]
	A:e -- X:w [penwidth=3.0 style="" color="#ffff00"]

	B:e -- Y:w [penwidth=9.0 color="#000000"]
	B -- Y [color="#ff0000"]
	B:e -- Y:w [penwidth=3.0 style="" color="#ffff00"]

	C -- Z [color="#ff0000"]
	C:e -- Z:w [penwidth=9.0 color="#000000"]
	C:e -- Z:w [penwidth=3.0 style="" color="#ffff00"]
}

```

without the red edge, the black and the yellow edge are drawn next to each other so that both edges are visible.  
If I add the red edge in between black and yellow, yellow is drawn exactly on top of the black edge. I would expect that the output is the same, if the red would be drawn first or last. But this is not the case here. I haven’t found any documentation about how the order of the edge definition matters to the drawing algorithm. Can you confirm that this behavior is intended?

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [July 23, 2020, 1:29am UTC](https://forum.graphviz.org/t/forcefully-draw-edges-on-top-of-each-other/266/4 "2020-07-23T01:29:05Z")

</div>

[NOTE: I am not a Graphviz developer, just a “friend of the family”. I don’t speak for the developers]  
Cool, I think you found a fascinating “accidental” result of a complex set of algorithms. Not documented that I know of, but not necessarily a bug. A gray area.  
But can you depend on it, probably, but let me suggest a “more” legal alternative.  
The basic idea is :

1. you define the complete graph _excluding_ all the “on-top” edges
2. run it through dot with this command: **dot -Tdot myfile.gv \>myfile.dot**
3. you modify (edit) **myfile.dot** duplicating the “bottom” edges to create the “top” edges

- change attribute values ( **color, penwidth, style, …** ) as needed
- this process can be done manually (see below), with any programming language, or with the Graphviz **GVPR** language  
Then run the edited myfile.dot through this command: **neato -n2 -Tpng myfie.dot \>myfile.png** (note the **-n2** option)  
The FAQ has a section that helps explain, as does the documentation on **dot** as an output file format  
Here is an example of the result of step 3:  
graph {  
graph [bb=“0,0,252,108”];  
node [label="\N"];  
A [height=0.5,  
pos=“27,90”,  
width=0.75];  
X [height=0.5,  
pos=“81,18”,  
width=0.75];  
A:e – X:w [color="#000000",  
penwidth=9.0,  
pos=“55,90 71.006,90 36.994,18 53,18”];  
// duplicated by hand  
A:e – X:w [color="#ff00ff",  
penwidth=3.0,  
pos=“55,90 71.006,90 36.994,18 53,18”];  
B [height=0.5,  
pos=“99,90”,  
width=0.75];  
Y [height=0.5,  
pos=“153,18”,  
width=0.75];  
B:e – Y:w [color="#000000",  
penwidth=9.0,  
pos=“127,90 143.01,90 108.99,18 125,18”];  
// again  
B:e – Y:w [color="#ffff00",  
penwidth=3.0,  
pos=“127,90 143.01,90 108.99,18 125,18”];  
C [height=0.5,  
pos=“171,90”,  
width=0.75];  
Z [height=0.5,  
pos=“225,18”,  
width=0.75];  
C:e – Z:w [color="#000000",  
penwidth=9.0,  
pos=“199,90 215.01,90 180.99,18 197,18”];  
// number 3  
C:e – Z:w [color="#00ffff",  
penwidth=3.0,  
pos=“199,90 215.01,90 180.99,18 197,18”];  
}

Convoluted, yes. But definitely within the bounds of legal.  
If you decide to try this, you could add “extra” attributes to the edges you wanted to duplicate like dup\_pen=3 and dupcolor=blue (documented as legal). to give instructions to your script.

---

<div class="post-metadata">

**Author:** ![snowmb](https://avatars.discourse-cdn.com/v4/letter/s/a183cd/32.png) [@snowmb](https://forum.graphviz.org/u/snowmb)\
**Post date:** [July 23, 2020, 1:49pm UTC](https://forum.graphviz.org/t/forcefully-draw-edges-on-top-of-each-other/266/5 "2020-07-23T13:49:59Z")

</div>

Wow I just play around with your suggestion and this is SUPER helpful. This solves basically all my problems, since I can force graphviz to layout some things for me and add to the layout later without it messing everything up. Very nice solution indeed! Thank you very much. I will come around later and show some results when I’m done with the scripting. 👍
