4

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:

Curved two-colored line between two nodes

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?

4

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! – Matt Menzenski Mar 19 '15 at 16:35
  • if I need three lines side by side? How could that be achieved? – Elena Feb 6 '17 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}}}. – Symbol 1 Feb 6 '17 at 15:34
5

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.

enter image description here

4

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}

enter image description here

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.