17

I would like to set up a presentation in which different parts of the same tikz picture appear, depending on the value of one, perhaps more, integer variables. I tried at first using a fixed picture, with changing the visibility of the different path elements of it, depending on the slide number, but this did not scale. There are about 150 slides in a single frame.

Then, I tried an alternative in which the entire picture is defined as a macro, which is invoked once per slide, with different portions showing based on global conditions. However, I failed in including conditionals within the keys.

Here is a not so minimal and certainly not working example demonstrating my failures. Any help would be appreciated:

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{chains}

        \tikzset{%
            invisible/.style={opacity=0},
        }

\newcounter{count}


\newcommand\myPicture{
\begin{tikzpicture}
  \begin{scope}[start chain = going right]
      \node[draw, circle, on chain] {
      \ifnum \value{count} > 1
      {Count is greater than s}
      \fi};
  \node[draw, circle, on chain,opacity=0] {B};
  \node[draw, circle, on chain,  \ifnum \value{count} > 1\relax invisible\fi] {C};
    \node[draw, circle, on chain] {D};
  \end{scope}
\end{tikzpicture}
}

\begin{document}


\begin{frame}
\setcounter{count}{2}
\ifnum \value{count} > 1
{Count is greater than 1}
\fi
\ifnum \value{count} > 2
{Count is greater than s}
\fi



\only{
\setcounter{count}{2}
\myPicture
}

\only{
\setcounter{count}{1}
\myPicture
}
\only{
\setcounter{count}{2}
\myPicture
}
\end{frame}
\end{document}

Here is a minimal example giving an idea of the expected result, but of course, without achieving it:

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{chains}
\newcounter{count}
\newcommand\myPicture{
\begin{tikzpicture}
  \begin{scope}[start chain = going below]
      \node[draw, rectangle, on chain] {display only when counter is between 1 and 3};
  \node[draw, rectangle, on chain] {display only when counter is negative}; %
  \node[draw, rectangle, on chain] {display only if counter is between 100 and 200};
  \node[draw, circle, on chain] {only when counter is in the range 3 to 20};
  \end{scope}
\end{tikzpicture}
}

\begin{document}
\begin{frame}
\only{\setcounter{count}{-3}\myPicture}
\only{\setcounter{count}{105}\myPicture}
\only{\setcounter{count}{39}\myPicture}
\only{\setcounter{count}{2}\myPicture}
\end{frame}
\end{document}
6
  • No, it is much more complicated than this. I am trying to run an animation of a fairly complex algorithm, and I would like the picture to follow the actual progress of the algorithm, which I emulate with my LaTeX code.
    – Yossi Gil
    Commented Jan 29, 2014 at 15:48
  • 2
    Note that beamer scans through the frame and creates slides based on each reading. What you have is read all the time so if conditionals are ambiguous depending on at which scan it is parsed. You might want to give an example of a drawing instead of these tests.
    – percusse
    Commented Jan 29, 2014 at 15:53
  • Yes, I know. I see no other alternative but making beamer work hard on each overlay. I added an example to give some indication on what is needed.
    – Yossi Gil
    Commented Jan 29, 2014 at 16:01
  • 1
    You could create each image separately and store them in saveboxes, then pull them up by name. (A,B,C is easier than 1,2,3 -- requires \csname.) Commented Jan 29, 2014 at 18:44
  • I am clueless as to how to do this, but then, I need the numbers, since they reflect the state of the algorithm.
    – Yossi Gil
    Commented Jan 29, 2014 at 18:50

2 Answers 2

7

I am definitely unfamiliar with both beamer and tikz (do not quite get what the \only are supposed to do) but perhaps this could go in the direction you want:

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{chains}
\newcounter{count}

% helper macro:
\long\def\GobToSemiColon #1;{}

\newcommand\myPicture{
\begin{tikzpicture}
  \begin{scope}[start chain = going below]
  \ifnum\value{count}<1 \expandafter\GobToSemiColon\fi
  \ifnum\value{count}>3 \expandafter\GobToSemiColon\fi
  \node[draw, rectangle, on chain] {display only when counter is between
    1 and 3};

  \ifnum\value{count}>-1 \expandafter\GobToSemiColon\fi
  \node[draw, rectangle, on chain] {display only when counter is
    negative}; 

  \ifnum\value{count}<100 \expandafter\GobToSemiColon\fi
  \ifnum\value{count}>200 \expandafter\GobToSemiColon\fi  
  \node[draw, rectangle, on chain] {display only if counter is between
    100 and 200};

  \ifnum\value{count}<3 \expandafter\GobToSemiColon\fi
  \ifnum\value{count}>20 \expandafter\GobToSemiColon\fi
  \node[draw, circle, on chain] {only when counter is in the range 3 to 20};
  \end{scope}
\end{tikzpicture}
}

\begin{document}
\begin{frame}
\only{\setcounter{count}{-3}\myPicture}
\only{\setcounter{count}{105}\myPicture}
\only{\setcounter{count}{39}\myPicture}
\only{\setcounter{count}{2}\myPicture}
\only{\setcounter{count}{5}\myPicture}
\end{frame}
\end{document}

beamer

3

I tried to modify your minimal example by introducing a changing tikzpicture depending on the value of an integer. To make the drawing stable on all the slides, I included a \clip action.

enter image description here

I couldn't quite figure out what your problem was and I imagine that the lapse of time between your question and my answer is not helping. Let me know if you are still looking for something else.

\documentclass{beamer}

\usepackage{xcolor}
\usepackage{tikz}
\usetikzlibrary{chains}

\newcounter{count}
\newcommand{\myPicture}[1]{%
  \begin{tikzpicture}
    \clip (-5, -3.3) rectangle (5, 3.3);
    \begin{scope}[start chain = going below]
      \ifnum#1<4
      \node[draw, rectangle, on chain, fill=yellow]
      {display only when counter is between 1 and 3};
      \node[on chain, red!50!black, fill=blue!50!black!10,
      inner sep=2ex, rounded corners, scale=1.25, rotate={(#1-1)*10}]
      {counter=#1};
      \else
      \ifnum#1<6
      \node[draw, rectangle, on chain, rounded corners]
      {display only when counter is 4 or 5};
      \else
      \ifnum#1=6
      \node[draw, rectangle, on chain]
      {display only when counter is 6 or 7};
      \else
      \ifnum#1=7
      \node[draw, rectangle, on chain,
      label={[fill=orange]-35:not so identical}]
      {display only when counter is 6 or 7};      
      \else
      \node[draw, very thick, blue, circle, on chain]
      {only when counter is 8, or \ldots};
      \fi\fi\fi\fi
  \end{scope}
\end{tikzpicture}
}

\begin{document}

\begin{frame}{Introduction}
  Some information on the first frame and an example with multiple slides based on a TikZ picture on the second one.
\end{frame}


\begin{frame}{A changing image on this frame}
  The inspiring test: (on slide \thepage\ -- total counting)

  \bigskip
  
  \only<1> {\myPicture{1}}
  \only<2> {\myPicture{2}}
  \only<3> {\myPicture{3}}
  \only<4-5> {\myPicture{4}}
  \only<6> {\myPicture{6}}
  \only<7> {\myPicture{7}}
  \only<8> {\myPicture{8}}
\end{frame}
\end{document}  

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .