2

I have a series of slides/transitions showing one matrix where I insert some gaps between columns and circle numbers and at one point add an extra row at the bottom. I would like the matrix to stay in the same place vertically and for all the elements (which are boxed) to stay in the same place when all I do is circle a number or add a row at the bottom of the matrix (see example for what this means exactly). Basically, I would like it to stop jumping around as much as possible. How can I do this?

Here is a rather long example which shows the problem:

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{arrows.meta, calc, matrix}
\newcommand\Circle[1]{%
    \tikz[baseline=(char.base)]\node[circle,draw,inner sep=2pt] (char) {#1};}

\begin{document}

\begin{frame}[fragile]
    \frametitle{title}
    \begin{center}
        \begin{tikzpicture}
        \matrix (m) [matrix of nodes,
        nodes={draw, minimum size=8mm},
        column sep=3mm,
        row sep=2mm,
        row 1/.style={nodes={draw=none}}]
        {
            0 & 1 & 2 & 3 & 4   \\[-3mm]
            6 & 2 & 4 & 4 & 5   \\
            8 & 4 & 5 & 6 & 6   \\
            7 & 5 & 2 & 7 & 5   \\
            6 & 5 & 1 & 6 & 5   \\
            5 & 9 & 0 & 2 & 4   \\
        };
        \end{tikzpicture}
    \end{center}

    \begin{itemize}
        \item A line of text
    \end{itemize}
\end{frame}

\begin{frame}[fragile]
    \frametitle{title}
    \begin{center}
        \begin{tikzpicture}
        \matrix (m) [matrix of nodes,
        nodes={draw, minimum size=8mm},
        column sep=3mm,
        row sep=2mm,
        row 1/.style={nodes={draw=none}}]
        {
            0 & 1 & 2 & 3 & 4   \\[-3mm]
            6 & 2 & 4 & 4 & 5   \\
            \Circle{8} & 4 & \Circle{5} & 6 & \Circle{6}   \\
            7 & 5 & 2 & \Circle{7} & 5   \\
            6 & 5 & 1 & 6 & 5   \\
            5 & \Circle{9} & 0 & 2 & 4   \\
            &   &   &   &     \\
            \hline \\
            8 & 9 & 5 & 7 & 6   \\
        };
        \end{tikzpicture}
    \end{center}

    \begin{itemize}
        \item Some text
    \end{itemize}
\end{frame}


\begin{frame}[fragile]
    \frametitle{title}
    \begin{center}
        \begin{tikzpicture}
        \matrix (m) [matrix of nodes,
        nodes={draw, minimum size=8mm},
        column sep=3mm,
        row sep=2mm,
        row 1/.style={nodes={draw=none}}]
        {
            0 & 1 &[5mm] 2 &[5mm] 3 & 4   \\[-3mm]
            6 & 2 & 4 & 4 & 5   \\
            8 & 4 & \Circle{5} & 6 & 6   \\
            7 & 5 & 2 & 7 & 5   \\
            6 & 5 & 1 & 6 & 5   \\
            5 & 9 & 0 & 2 & 4   \\
            &   &   &   &     \\
            \hline \\
            8 & 9 & 5 & 7 & 6   \\
        };
        \end{tikzpicture}
    \end{center}

\end{frame}

\begin{frame}[fragile]
    \frametitle{title}
    \begin{center}
        \begin{tikzpicture}
        \matrix (m) [matrix of nodes,
        nodes={draw, minimum size=8mm},
        column sep=3mm,
        row sep=2mm,
        row 1/.style={nodes={draw=none}}]
        {
            0 & 1 &[5mm] 2 & 3 & 4   \\[-3mm]
            6 & 2 & 4 & 4 & 5   \\
            8 & 4 & 5 & 6 & 6   \\
            7 & 5 & 2 & 7 & 5   \\
            6 & 5 & 1 & 6 & 5   \\
            5 & 9 & 0 & 2 & 4   \\
            &   &   &   &     \\
            \hline \\
            8 & 9 & 5 & 7 & 6   \\
        };
        \end{tikzpicture}
    \end{center}
\end{frame}

\begin{frame}[fragile]
    \frametitle{title}
    \begin{center}
        \begin{tikzpicture}
        \matrix (m) [matrix of nodes,
        nodes={draw, minimum size=8mm},
        column sep=3mm,
        row sep=2mm,
        row 1/.style={nodes={draw=none}}]
        {
            0 & 1 & 2  &[5mm] 3 &[5mm]  4   \\[-3mm]
            6 & 2 & 4 & 4 & 5   \\
            8 & 4 & 5 & 6 & 6   \\
            7 & 5 & 2 & 7 & 5   \\
            6 & 5 & 1 & 6 & 5   \\
            5 & 9 & 0 & 2 & 4   \\
            &   &   &   &     \\
            \hline \\
            8 & 9 & 5 & 7 & 6   \\
        };
        \end{tikzpicture}
    \end{center}
\end{frame}

\begin{frame}[fragile]
    \frametitle{title}
    \begin{overlayarea}{\linewidth}{\textheight}
    \begin{center}
        \begin{tikzpicture}
        \matrix (m) [matrix of nodes,
        nodes={draw, minimum size=8mm},
        column sep=3mm,
        row sep=2mm,
        row 1/.style={nodes={draw=none}}]
        {
            0 & 1 & 2  &[5mm] 3 &[5mm]  4   \\[-3mm]
            6 & 2 & 4 & 4 & 5   \\
            8 & 4 & 5 & 6 & 6   \\
            7 & 5 & 2 & \Circle{7} & 5   \\
            6 & 5 & 1 & 6 & 5   \\
            5 & 9 & 0 & 2 & 4   \\
            &   &   &   &     \\
            \hline \\
            8 & 9 & 5 & 7 & 6   \\
        };
        \end{tikzpicture}
    \end{center}
    \pause
    \begin{itemize}
        \item More text 
    \end{itemize}
\end{overlayarea}
\end{frame}
\end{document}
  • Your approach nests tikzpictures. This is to be avoided. I compiled your code and see what it does, but fail to understand what you mean by "I move columns of a matrix from left to right". As far as I can see the matrix gets largely preserved but only some gaps and circles appear. Could you please explain what you mean by that statement? – Schrödinger's cat Feb 1 at 18:28
  • Typically, if tikzpictures are moving around it is because the bounding box changes. You need to use a common (larger) bounding box for all the tikzpictures. See tex.stackexchange.com/questions/490497/… – John Kormylo Feb 1 at 18:34
  • @Schrödinger'scat That is exactly what I meant. Sorry it was unclear. – Arlo Feb 1 at 18:39
  • @JohnKormylo When I circle a number it also increases the size of the surrounding box, which is fine but also seems to cause some jumping about. – Arlo Feb 1 at 18:43
  • Instead of putting a circle IN the matrix, overlay it. Each cell has a node name which can be used to locate it after the matrix is complete. – John Kormylo Feb 1 at 18:48
3

I'd draw the matrix just once and use overlay-beamer-styles to add the changes. Your \Circled command nests tikzpictures, I replaced it by a circled style and a variation circled on which adds the circle only on some specific overlays. E.g.

|[circled on=<{2,6,7}>]| 7

circles the 7 node only on overlays 2, 6 and 7. I also added one example how you can use the alt key to change the column sep of specific columns on certain overlays,

alt=<2>{column 2/.style={column sep=7mm},column 3/.style={column sep=7mm}}{},

but I did not have the passion to implement all of them.

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{arrows.meta, calc, matrix,overlay-beamer-styles}
\tikzset{circled/.style={path picture={
 \draw let \p1=($(path picture bounding box.north east)-(path picture bounding
 box.south west)$),\n1={min(\x1,\y1)/2.2} in
 (path picture bounding box.center) circle[radius=\n1];}},
circled on/.style={alt=#1{circled}{}}}
\begin{document}
\begin{frame}[fragile,t]
\frametitle{title}
\centering
\begin{tikzpicture}
    \matrix (m) [matrix of nodes,
    nodes={draw, minimum size=8mm},
    column sep=3mm,
    alt=<2>{column 2/.style={column sep=7mm},column 3/.style={column sep=7mm}}{},
    % you need to add the other variations of the column seps here
    row sep=2mm,
    row 7/.style={visible on=<4-5>},
    row 1/.style={nodes={draw=none}}] (mat)
    {
        0 & 1 & 2 & 3 & 4   \\[-3mm]
        6 & 2 & 4 & 4 & 5   \\
         |[circled on=<2>]| 8 & 4 &  |[circled on=<{2,3}>]| 5 & 6 &  |[circled on=<2>]| 6   \\
        7 & 5 & 2 & |[circled on=<{2,6,7}>]| 7 & 5   \\
        6 & 5 & 1 & 6 & 5   \\
        5 & |[circled on=<2>]| 9 & 0 & 2 & 4   \\[2mm]
        8 & 9 & 5 & 7 & 6   \\
    };
    \path (mat-6-1.south) -- (mat-7-1.north) coordinate[midway](aux);
    \draw[visible on=<{4,5}>] (mat.west|-aux) -- (mat.east|-aux);
    \end{tikzpicture}


\only<1>{\begin{itemize}
 \item A line of text
\end{itemize}}
\only<2>{\begin{itemize}
 \item Some text
\end{itemize}}
\only<7>{\begin{itemize}
 \item More text
\end{itemize}}
\end{frame}
\end{document}

enter image description here

As you see, no more jumps and much shorter code (and, even though you may not necessarily see it this way, most importantly no more nested tikzpictures).

ADDENDUM: Added an extra row that is only visible on certain overlays, and separated by a line. The visibility is controlled by

row 7/.style={visible on=<4-5>},

and

\draw[visible on=<{4,5}>] (mat.west|-aux) -- (mat.east|-aux);

respectively.

|improve this answer|||||
  • This is almost miraculously better than my code! I can't upvote as my reputation is too low. – Arlo Feb 1 at 19:14
  • How can add the horizontal line and the extra row (as in my example code) using your very nice new solution? Currently I just add an \hline, a blank row and an extra row but this needs to be shown only for some overlays now without making it jump around. – Arlo Feb 1 at 19:46
  • 1
    @Arlo I added horizontal lines. Please note that \hline sort of works by accident, so I use a more robust way. – Schrödinger's cat Feb 1 at 20:31
  • Thanks but in my case I am adding an extra row below the existing matrix with a horizontal line in between. I tried using \only{} for the extra row but that failed completely. – Arlo Feb 1 at 21:52
  • 1
    @Arlo I added the code for this. – Schrödinger's cat Feb 1 at 22:09

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.