[Tex/LaTex] Drawing 2-ring network with TikZ

graphstikz-pgf

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.

Best Answer

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.

Related Question