# Two parallel curved edges in Tikz (Or, one curved edge with two colors side-by-side)

I'm working on a series of (linguistic) diagrams in which nodes are connected by lines. Some lines need to bend to go around other nodes. Each diagram has 16 nodes and lots of lines (>50).

Ideally, I'd be able to draw some lines in two colors. I'd like to do them side-by-side, and I can't figure out a way to achieve that (at least, in a way that scales easily for many lines).

Here's a minimal example showing the sort of line I'd like to get:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\coordinate (one)    at (2,0);
\coordinate (oneb)   at (2,0.05);
\coordinate (two)    at (0,0);
\coordinate (three)  at (-2,0);
\coordinate (threeb) at (-2,0.05);
\path (one) edge[blue, very thick, bend left=40] (three);
\path (oneb) edge[red, very thick, bend left=40] (threeb);
\path (three) edge[red, very thick, bend left=40] (one);
\filldraw[draw=black,fill=white] (one)   circle (0.2in);
\filldraw[draw=black,fill=white] (two)   circle (0.2in);
\filldraw[draw=black,fill=white] (three) circle (0.2in);
\node at (one)   {one};
\node at (two)   {two};
\node at (three) {three};
\end{tikzpicture}
\end{document}


This results in the following:

This method (defining new coordinates) works well enough when there's only one line to draw, but it's not feasible when there are many lines in many different directions.

Is there a simpler way to define a two-color edge like the lower line in the above example?

I have a tricky way using postaction

\documentclass[tikz,border=9]{standalone}
\begin{document}
\tikzset{
side by side/.style 2 args={
line width=2pt,
#1,
postaction={
clip,postaction={draw,#2}
}
},
circle node/.style={
circle,
draw,
fill=white,
minimum size=1.3cm
}
}
\begin{tikzpicture}
\node[circle node](one)at(2,0){one};
\node[circle node](two)at(0,0){two};
\node[circle node](three)at(-2,0){three};
\path(one)edge[blue,bend left](three);
\path(one)edge[side by side={green}{blue},bend right](three);
\end{tikzpicture}


If you found wedge-like ends annoying, you may also cover them by nodes.

\begin{tikzpicture}
\node(one)at(2,0){};
\node(two)at(0,0){};
\node(three)at(-2,0){};
\path(one)edge[blue,bend left=50](three);
\path(one)edge[side by side={green}{blue},bend right=50](three);
\node[circle node]at(one){one};
\node[circle node]at(two){two};
\node[circle node]at(three)at(-2,0){three};
\end{tikzpicture}
\end{document}
\end{document}

• This does exactly what I need, and it's easily applied to my existing code. Many thanks! Commented Mar 19, 2015 at 16:35
• if I need three lines side by side? How could that be achieved? Commented Feb 6, 2017 at 14:22
• @Elena Ask a followup question; or, try to use two layers of postaction with suitable line width. For example .style={draw blue line,postaction={draw green line,postaction={draw red line}}}. Commented Feb 6, 2017 at 15:34

Dan Luecking, the maintainer of the mfpic package, a (La)TeX interface to MetaPost, has designed a \parallelpath macro for this sort of task. It has to be placed before the path it must shift, and it takes as argument the amount of shifting to the left, in the user's coordinate (here the centimeter). ‘‘Left’’ is to be understood as the left direction for someone who would walk along the path.

Dan Luecking warns the user that this macro could produce weird results with complicated paths (e.g. with tight turns). See the mfpic manual, p.32.

It would be interesting to see how this macro is defined in the underlying MetaPost-based engine of mfpic. I will look at it as soon as I have more time.

\documentclass{article}

\usepackage[metapost, mplabels, truebbox]{mfpic}
\mfpverbtex{%&latex
\documentclass{article}
\begin{document}}
\setlength{\mfpicunit}{1cm}
\opengraphsfile{\jobname}

\begin{document}
\begin{mfpic}[1]{-2}{2}{-1}{1}
\setmfpair{A}{(-2, 0)}
\setmfpair{B}{(2, 0)}
\setmfvariable{path}{line}{A{dir -40} .. {dir 40}B}
\penwd{1bp}
\draw[red]\parallelpath{-0.5*0.035}\mfobj{line}
\draw[blue]\parallelpath{0.5*0.035}\mfobj{line}
\draw[red]\reflectpath{A, B}\mfobj{line}
\penwd{.5bp}
\tlpathsep{2bp}
\setrender{\draw\gclear}
\circle{A, .5}\tlabel[cc]{A}{three}
\circle{origin, .5}\tlabel[cc]{origin}{two}
\circle{B, .5}\tlabel[cc]{B}{one}
\end{mfpic}
\closegraphsfile
\end{document}


0.035 is an approximate value in centimeter of a PostScript point (bp). Since I chose 1 bp as the thickness of the curved lines (\penwd{1bp}), the amount of displacement to be given as argument to \parallelpath must be -0.5*0.035 and 0.5*0.035 respectively.

Process it with (PDF)LaTeX, then with MetaPost, then again with (PDF)LaTeX.

Hoping that I didn't miss anything and understood properly, you can use node.angle if you have defined nodes.

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\node[circle,draw,minimum size=1.3cm] (one) at (2,0)   {one};
\node[circle,draw,minimum size=1.3cm] (two) at (0,0)   {two};
\node[circle,draw,minimum size=1.3cm] (three) at (-2,0) {three};
\path (one.210) edge[blue, very thick, bend left=40] (three.330);
\path (one.150) edge[red, very thick, bend right=40] (three.30);
\path (one.213) edge[red, very thick, bend left=40] (three.327);
\end{tikzpicture}
\end{document}


• Your nodes may have different sizes, then you have to adjust the angles suitably.
– user11232
Commented Mar 19, 2015 at 5:56
• Why not use bend left=40 with bend left=44? Or is not it side-by-side? Commented Mar 19, 2015 at 6:55
• @Symbol1 They won't be parallel, I hope.
– user11232
Commented Mar 19, 2015 at 6:56

With the great nfold library this is much easier now. Especially for not-closed path with no weird angles.

For a more general solution (more than two colors or with spacing between them) more work is necessary.

It should be noted that the cd library (tikz-cd) comes with shift left and shift right which can be applied to every TikZ path (not just \arrows) however it works a bit different (and shifts the edge orthogonal to a straight line connecting the nodes) but would produce the same for straight lines.

## Code

\documentclass[tikz]{standalone}
\usetikzlibrary{nfold}
\makeatletter
\tikzset{
side by side/.style args={#1:#2}{
postaction={path only,draw=#1,offset=+.5\pgflinewidth},
postaction={path only,draw=#2,offset=+-.5\pgflinewidth}},
side by side'/.style={path only,side by side={#1}},
offset/.code=
\pgfgetpath\tikz@temp
\pgfsetpath\pgfutil@empty
\pgfoffsetpath\tikz@temp{#1}}}
\makeatother
\begin{document}
\begin{tikzpicture}[x=2cm, text width=width("three"), align=center]
\node foreach[count=\i]\t in {one, two, three}
[draw, circle] (\t) at (-\i,0) {\t};
\path[thick] (one) edge[bend right]                       (three)
edge[side by side'=blue:red, bend left] (three);
\end{tikzpicture}
\end{document}


## Output

• It should just be draw=none instead of path only in the side by side' defintion. Commented Jun 15, 2023 at 7:36