1

I am trying to draw a Knodel graph using TikZ. The graph I am trying to reproduce has different style edges for each "dimension". I would like to have different edges for the different values of Delta in my foreach loop.

(A separate problem I am having is rotating the graph to look like the below)

Here is a figure from a paper that I am trying to reproduce: Knodel graph (figure 1) from paper

Here is what I have so far: enter image description here

Here is my code:

\documentclass[tikz,border=5mm]{standalone}
\usepackage{xparse}

\begin{document}

%from https://tex.stackexchange.com/a/175520
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\floor}{m}
 {
  \fp_eval:n { floor ( #1 ) }
 }
\ExplSyntaxOff

\tikzstyle{vertex}=[draw, circle, fill=black, inner sep=0.55mm]

\newcommand \knodel[2]{
    \def\N{#1}
    \def\Nhalf{\floor{\N}}
    \def\Delta{#2}

    %make the vertices
    \foreach \j in {0, ..., \numexpr \Nhalf - 1}{
            \node[label=left:{\small (1, \j)}] at (1, \j) [vertex] {};
        }
    \foreach \j in {0, ..., \numexpr \Nhalf - 1}{
            \node[label=right:{\small (2, \j})] at (2, \j) [vertex] {};
        }

    %draw the edges
    \foreach \j in {0, ..., \numexpr \Nhalf - 1}{
        \foreach \k in {0, ..., \numexpr \Delta - 1}{
            %\draw (1,j) to (2, (j + 2^k - 1) mod floor(n/2));
            \pgfmathtruncatemacro \target{mod(\j + (2^\k) - 1,\Nhalf)}
            \draw (1, \j) to (2, \target);
        }
    }
}

\begin{tikzpicture}

\knodel{8}{3}

\end{tikzpicture}
\end{document}
1
  • I am trying to resize the image, but none of the answers at this post seem to work well...
    – Abraham
    Feb 28, 2019 at 16:46

1 Answer 1

1

Aren't these just simple modulo arithmetics?

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{amsmath}
\newcommand{\kaspressknodel}[2]{\pgfmathtruncatemacro{\mymod}{#1+1}
  \foreach \X in {0,...,#1}
   {\node[bullet,label={right:$\boldsymbol{(2,\X)}$}] (v2\X) at 
   (4,{1.2*(\X-(#1+0)/2)}){};
   \node[bullet,label={left:$\boldsymbol{(1,\X)}$}] (v1\X) at 
   (1.5,{1.2*(\X-(#1+0)/2)}){};}
  \foreach \X [evaluate=\X as \NextX using {int(mod(\X+3,\mymod))},
  evaluate=\X as \AnotherX using {int(mod(\X+1,\mymod))},] in {0,...,#1}
  {\draw[thick] (v1\X) -- (v2\NextX);
  \draw[dashed] (v1\X) -- (v2\AnotherX);
  \draw (v1\X) -- (v2\X);} 
}
\begin{document}
\begin{tikzpicture}[bullet/.style={circle,inner sep=2pt,fill}]
 \begin{scope}[local bounding box=left]
    \kaspressknodel{6}{3} 
 \end{scope}
 %
 \begin{scope}[local bounding box=legend,shift={(left.east)}]
  \foreach \X [count=\Y starting from 0] in {solid,dashed,thick}
  {\draw[\X] (0.5,1-\Y) --++ (1,0) node[right]{dim~\Y};}
 \end{scope}
 \begin{scope}[local bounding box=right,shift={(legend.east)}]
    \kaspressknodel{3}{3} 
 \end{scope}
\end{tikzpicture}
\end{document}

enter image description here

A more TikZy way to obtain the same result is

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{amsmath}
\tikzset{pics/.cd,
kaspressknodel/.style n args={2}{code={\pgfmathtruncatemacro{\mymod}{#1+1}
  \foreach \X in {0,...,#1}
   {\node[bullet,label={right:$\boldsymbol{(2,\X)}$}] (v2\X) at 
   (4,{1.2*(\X-(#1+0)/2)}){};
   \node[bullet,label={left:$\boldsymbol{(1,\X)}$}] (v1\X) at 
   (1.5,{1.2*(\X-(#1+0)/2)}){};}
  \foreach \X [evaluate=\X as \NextX using {int(mod(\X+3,\mymod))},
  evaluate=\X as \AnotherX using {int(mod(\X+1,\mymod))},] in {0,...,#1}
  {\draw[thick] (v1\X) -- (v2\NextX);
  \draw[dashed] (v1\X) -- (v2\AnotherX);
  \draw (v1\X) -- (v2\X);} 
}}}
\begin{document}
\begin{tikzpicture}[bullet/.style={circle,inner sep=2pt,fill}]
 \pic[local bounding box=left] {kaspressknodel={6}{3}}; 
 %
 \begin{scope}[local bounding box=legend,shift={(left.east)}]
  \foreach \X [count=\Y starting from 0] in {solid,dashed,thick}
  {\draw[\X] (0.5,1-\Y) --++ (1,0) node[right]{dim~\Y};}
 \end{scope}
 %
 \pic[local bounding box=right,shift={(legend.east)}] {kaspressknodel={3}{3}}; 
\end{tikzpicture}
\end{document}

And then compressing the picture is as simple as e.g. \pic[local bounding box=left,yscale=0.8] {kaspressknodel={6}{3}};, where yscale=0.8 was added to reduce the height. You can then also rotate the diagrams or change their color.

4
  • How can I modify your code to have it variable based on values for \N and \Delta?
    – Abraham
    Feb 28, 2019 at 17:03
  • @Abraham I added such a code.
    – user121799
    Feb 28, 2019 at 17:14
  • +1 for evaluate ... as ..., this helped a lot! Thanks for this and for your edit, it's very helpful :-) Also thanks for showing a way to draw two graphs with a key in the middle!
    – Abraham
    Feb 28, 2019 at 17:38
  • 1
    @Abraham You're welcome!
    – user121799
    Feb 28, 2019 at 17:44

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.