23

I want to draw a graph like in the second picture of the following code:

\documentclass{article}
\usepackage{mathptmx}
\usepackage{tikz}
\usepackage{verbatim}
\usetikzlibrary{arrows,shapes,graphs,graphs.standard,quotes}
\usepackage{calc}% http://ctan.org/pkg/calc
\usepackage{ifthen}

\begin{document}

% This one works
\begin{tikzpicture}

\foreach \x in {1,...,5}
{ \node[circle,draw] (\x 1) at (0,\x) {\x};
    \node[circle,draw] (\x 2)at (2,\x) {\x};
    \ifthenelse{\NOT 4 = \x \AND \NOT 7 = \x}{\draw (\x 1) -- (\x 2);}{} % (*)
}

\end{tikzpicture}

% This one does not work with line (*)
\begin{tikzpicture}
\tikzstyle{vertex}=[circle,fill=blue!15,draw,minimum size=17pt,inner sep=0pt]

%See TikZ documentation! (Section 19, graphs)
\graph[circular placement, radius=4cm, group polar shift=(360/5:0),
         nodes={circle,draw,vertex}] {
    \foreach \x [evaluate=\x as \sx using int(\x+1)] in {0,...,4} {
      \foreach \y in {\x,...,4} {
        \x -- \y;
        %\ifthenelse{\NOT 4 = \x \AND \NOT 7 = \x}{\draw (\x 1) -- (\x 2);}{} % (*)
      };
    };
  };
\end{tikzpicture}

\end{document}

It uses the TikZ graph library. As you might guess, I want to label the edges dependent on what \x and \y are in the for loop. So I need an If-Then-Else statement and came to this answer: https://tex.stackexchange.com/a/45907/52709. I copied the code, it is the first picture and it works. But applying the same \ifthenelse-line to my code (commented out), produces an error at that line:

! Undefined control sequence.<argument> \NOT 4 = \x \AND \NOT 7 = \x }

and also

! Illegal parameter number in definition of \tikz@lib@graph@name.

at the end of the graph defintion (};).

Isn’t it possible to use something like \ifthenelse inside such a graph definition? How can I achieve what I need?

  • 2
    You have to remember that Tikz does its own parsing. Everything from \path (for example) to the terminating semicolon is parsed by Tikz. Outside these areas you can add any latex commands you want. – John Kormylo Jul 1 '14 at 16:22
  • Right, so this means I can't use \ifthenelse? Is there another way to do it? – user905686 Jul 1 '14 at 16:27
  • 1
    pgfmath contains its own ifthenelse, sort of. – John Kormylo Jul 1 '14 at 16:33
  • Evey (x,y) coordinate is passed through \pgfmathparse automatically. – John Kormylo Jul 1 '14 at 16:41
  • Since you are using tikz graphs, which require Lua, you can use lua too to evaluate your conditionals. I was trying to compose a MWE as proof of concept, but then I realized I didn't really understand the purpose of the conditions. What kind of output do you expect? Your example code compares \x with 4 an 7, but that doesn't makes much sense, and it does not use \y. – JLDiaz Jul 1 '14 at 18:11
24

\ifthenelse is "normal" LaTeX code. Therefore you can not use this command inside a TikZ path specification. But since the node text is put in a normal TeX box you can use \ifthenelse inside the node text. So you can try

\documentclass[tikz,margin=5mm]{standalone}
\usetikzlibrary{graphs,graphs.standard,quotes}

\usepackage{ifthen}

\begin{document}
\begin{tikzpicture}[
  vertex/.style={circle,fill=blue!15,draw,minimum size=17pt,inner sep=0pt}
]
%See TikZ documentation! (Section 19, graphs)
\graph[circular placement, radius=4cm, group polar shift=(360/5:0),
         nodes={circle,draw,vertex}] {
    \foreach \x in {0,...,4} {
      \foreach \y in {\x,...,4} {
        \x --["\ifthenelse{\x=3 \OR \y=3 \OR \x=\y}{}{\x\y}",sloped] \y;
  }}};
\end{tikzpicture}
\end{document}

enter image description here

Or you can position the nodes inside the \graph and connect them outside. Then you can use \ifthenelse outside of a path specification. Note that the complete \draw paths are in the arguments of \ifthenelse.

\documentclass[tikz,margin=5mm]{standalone}
\usetikzlibrary{graphs,graphs.standard,quotes}

\usepackage{ifthen}

\begin{document}
\begin{tikzpicture}[
  vertex/.style={circle,fill=blue!15,draw,minimum size=17pt,inner sep=0pt}
]
%See TikZ documentation! (Section 19, graphs)
\graph[circular placement, radius=4cm, group polar shift=(360/5:0),
         nodes={circle,draw,vertex}] {\foreach \x in {0,...,4} \x;
};
\foreach \x in {0,...,4} {
  \foreach \y in {\x,...,4} {
    \ifthenelse{\x=3 \OR \y=3 \OR \x=\y}{\draw(\x)--(\y);}{\draw(\x)--node[auto,sloped]{\x\y}(\y);}
}}
\end{tikzpicture}
\end{document}

The result is the same as above.


In the pgfmanual you can also find \pgfextra as a possibilty to suspend temporarly the path construction and do some other things like \ifthenelse. Here is a simple example where the filling color depends on the counter:

\documentclass[tikz,margin=5mm]{standalone}
\newcommand\mycolor{blue!15}
\usepackage{ifthen}
\begin{document}
    \begin{tikzpicture}[
        vertex/.style={circle,draw,minimum size=17pt,inner sep=0pt}
      ]
  \foreach \i in {0,...,4}{
    \path(0,0)\pgfextra{\ifthenelse{\i=2}{\def\mycolor{red!15}}{}}
      (90+\i*72:1)node[vertex,fill=\mycolor]{\i};}
\end{tikzpicture}
\end{document}

This results in

enter image description here

But AFAIK this does not work inside a \graph command.


Update:

Solutions without package \ifthen based on a suggestion of @marmot in a comment:

\documentclass[tikz,margin=5mm]{standalone}
\usetikzlibrary{graphs,graphs.standard,quotes}

\begin{document}
\begin{tikzpicture}[
  vertex/.style={circle,fill=blue!15,draw,minimum size=17pt,inner sep=0pt}
]
%See TikZ documentation! (Section 19, graphs)
\graph[circular placement, radius=4cm, group polar shift=(360/5:0),
         nodes={circle,draw,vertex}] {
    \foreach \x in {0,...,4} {
      \foreach \y 
        [evaluate=\y as \z using {int(ifthenelse(\x==3 || \y==3 || \x==\y,1,0))}]
        in {\x,...,4} {
        \x --["\ifnum \z=0 {\x\y}\fi",sloped] \y;
  }}};
\end{tikzpicture}
\end{document}

or

\documentclass[tikz,margin=5mm]{standalone}
\usetikzlibrary{graphs,graphs.standard,quotes}

\begin{document}
\begin{tikzpicture}[
  vertex/.style={circle,fill=blue!15,draw,minimum size=17pt,inner sep=0pt}
]
%See TikZ documentation! (Section 19, graphs)
\graph[circular placement, radius=4cm, group polar shift=(360/5:0),
         nodes={circle,draw,vertex}] {\foreach \x in {0,...,4} \x;
};
\foreach \x in {0,...,4} {
  \foreach \y 
    [evaluate=\y as \z using {int(ifthenelse(\x==3 || \y==3 || \x==\y,1,0))}]
    in {\x,...,4} {
      \ifnum \z=1
        \draw(\x)--(\y);
      \else 
        \draw(\x)--node[auto,sloped]{\x\y}(\y);
      \fi
}}
\end{tikzpicture}
\end{document}

The result is the same as in the first picture.

| improve this answer | |
  • This is exactly what I need! Can you please add an explanation why this works and where you can use \ifthenelse and where not? Thanks! – user905686 Jul 2 '14 at 11:40
  • I have edited my answer. – esdd Jul 2 '14 at 20:35
  • 2
    Maybe add \foreach \x in {0,...,4} { \foreach \y [evaluate=\y as \z using {int(ifthenelse(\x==3 || \y==3 || \x==\y,1,0))}] in {\x,...,4} { \ifnum\z=1 \draw(\x)--(\y); \else \draw(\x)--node[auto]{\x\y}(\y); \fi }} to the list of possibilities. It does not require the ifthenelse package. – user121799 Jun 21 '19 at 1:05
7

You can pre-compute an array of points using \ifthenelse, then use them in the \foreach. I have no idea what you are trying to accomplish with the second example.

\documentclass{article}
\usepackage{mathptmx}
\usepackage{tikz}
\usepackage{verbatim}
\usetikzlibrary{arrows,shapes,graphs,graphs.standard,quotes}
\usepackage{calc}% http://ctan.org/pkg/calc
\usepackage{ifthen}

\begin{document}
\begin{tikzpicture}

\def\xset{1,2,3,5}% sort of obvious

\def\xset{\strut}% doing it the hard way
\foreach \x in {1,...,5}
  {\ifthenelse{\NOT 4 = \x \AND \NOT 7 = \x}
  {\if\xset\strut\relax\global\edef\xset{\x}\else\global\edef\xset{\xset,\x}\fi}
  {}};

\foreach \x in {1,...,5}
{ \node[circle,draw] (\x 1) at (0,\x) {\x };
    \node[circle,draw] (\x 2) at (2,\x) {\x };
}
\foreach \x in \xset {\draw (\x 1) -- (\x 2);};

\end{tikzpicture}
\end{document}
| improve this answer | |
  • A nice workaround if you cannot use \ifthenelse, but in this case I'd prefer esdd's answer. – user905686 Jul 2 '14 at 11:48

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.