4

I'd like to draw a 2-ring directed graph as shown in the picture below.

hand-drawn image

I first tried the following code, and it seems to be somewhat successful.

\RequirePackage{luatex85}
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{graphdrawing,graphs}
\usegdlibrary{circular}
\begin{document}
\tikz
\graph [simple necklace layout, nodes={circle,draw}, horizontal = 2 to 3] {
  1 -> {2 -> 3, 3},
  5 -> {4 <- 6, 6},
  1 -> 4,
  2 <- 5,
  3 <- 6
};
\end{document}

MWE

The result of MWE is isomorphic to my hand-drawn picture from the viewpoint of graph theory, but it doesn't look nice. I'd like it to appear as two concentric circular (or triangular) rings.

I can draw this kind of stuff manually (i.e., directly specifying the placement of nodes using \foreach etc.), but this isn't an approach I want. I'm now learning some "automatic" way of drawing such graphs with the aid of graphs/graphdrawing libraries.

Are the any useful keys to achieve this? I'm now consulting the documentation, but haven't found a solution yet.

  • 1
    If you want to have a specific arrangement of nodes, graphdrawing is not the right tool. – Henri Menke Jul 19 '17 at 5:44
  • @HenriMenke You mean it's hard to take full control of arrangements because algorithms in Lua take care of it? – yudai-nkt Jul 19 '17 at 6:26
9

If you really want an automated approach I suggest looking at tkz-berge:

\documentclass[border=2mm]{standalone}
\usepackage{tkz-berge}
\usetikzlibrary{arrows,decorations.markings}

\tikzset{%
  ->-/.style={decoration={markings, mark=at position 0.5 with {\arrow{stealth}}},
              postaction={decorate}}
}

\begin{document}

    \begin{tikzpicture}
      \GraphInit[vstyle=Shade]% shade nodes
      \tikzset{EdgeStyle/.style={->-,thick,brown}}% add edge styling
      \SetVertexNoLabel %turn off default labels 
      \grPrism[RA=6,RB=3]{3}% draw the graph
      \AssignVertexLabel{a}{4,5,6}% add labels from OP
      \AssignVertexLabel{b}{1,2,3}
    \end{tikzpicture}

\end{document}

Modulo one edge, this produces the graph you want, albeit with straight edges:

enter image description here

If you are happy with an undirected graph with vertices labeled a_1,a_2,a_3,b_1,b_2,b_3 then the code inside the tikzpicture environment can be shortened to just \grPrism[RA=6,RB=3]{3}! By using explicit \Edge commands you can change the direction of the errant edge from 1 to 4 so that it points in the direction in the OP, but I do not see an "automatic" way of doing this. To get curved lines you almost certainly need to specify all of the edges separately using \Edge commands, together with appropriate bend left/right or in=..., out=... specifications.

Personally, even though you say you don't want this, I would just draw this graph using normal tikz commands. The problem is that, except for standard graphs, there is unlikely to be an "automatic" way to draw them nicely. If you are happy with straight edges this is relatively straightforward:

\documentclass[border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows,decorations.markings}

\tikzset{%
  ->-/.style={decoration={markings, mark=at position 0.5 with {\arrow{stealth}}},
              postaction={decorate}}
}

\begin{document}

    \begin{tikzpicture}
      \foreach \pt/\r/\ang in {1/1/90,2/1/210,3/1/330,4/3/90,5/3/210,6/3/330} {
         \node[circle,draw] (\pt) at (\ang:\r){\pt};
      }
      \foreach \x/\y in {1/2,2/3,3/1,1/4,5/2,6/3,5/4,5/6,6/4} {% draw the edges
         \draw[->-] (\x) -- (\y);
      }
    \end{tikzpicture}

\end{document}

This code produces:

enter image description here

If you want to have curved edges then one way to do this is to draw the circles first and put edges on top of them afterwards:

\documentclass[border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows,decorations.markings}

\tikzset{%
  ->-/.style={decoration={markings, mark=at position 0.5 with {\arrow{stealth}}},
              postaction={decorate}}
}

\begin{document}

    \begin{tikzpicture}
      \draw (0,0) circle [radius=1];
      \draw (0,0) circle [radius=3];
      \foreach \pt/\r/\ang in {1/1/90,2/1/210,3/1/330,4/3/90,5/3/210,6/3/330} {
         \node[circle,draw,fill=white] (\pt) at (\ang:\r){\pt};
      }
      \foreach \x/\y in {5/2, 6/3, 1/4} {
         \draw[->-] (\x) -- (\y);
      }
      \foreach \ang in {30,150,270} {% draw remaining edges
           \draw[->-] (\ang-1:1) -- (\ang+1:1);
           \draw[->-] (\ang-1:3) -- (\ang+1:3);
      }
    \end{tikzpicture}

\end{document}

This produces the following diagram, which is closer to your picture:

enter image description here

In all cases I have used the tikz decorations.markings library to define a "new" arrow type, ->-, that puts an arrow head in the middle of an edge. For the pure tikz solutions I have used polar coordinates, and a \foreach-loop, to place the nodes.

  • I actually was interested in tkz-berge, but I thought it supported only undirected graphs. That isn't the case though (tkz-graph seems to support). Thank you for your very elaborative answer, and I'll try the package later. – yudai-nkt Jul 19 '17 at 9:42
  • @yudai-nkt tkz-berge is tikz with lots of extra code on top. Consequently, you can add the usual tikz styling on top of it and do lots of other fun things with it. – Andrew Jul 19 '17 at 9:45

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.