1

In this example I am using overlayarea to develop a tikz picture over slides:

\documentclass{beamer}
\usepackage{tikz}
\begin{document}
\begin{frame}
    \begin{overlayarea}{\linewidth}{0.9\paperheight}
      \centering
      \begin{tikzpicture}
        \draw[red, very thick](0, 0) -- (3, 0);
        \only<1>{
          \draw(-1, 1) -- (2, 1);
        }
        \only<2>{
          \draw(-2, 2) -- (1, 2);
        }
      \end{tikzpicture}
    \end{overlayarea}
  \end{frame}
\end{document}

Unfortunately, the coordinate system gets readjusted on each slide as evidenced by the jumping of the red thick anchor line:

enter image description here

How to use the same coordinates on each slide when using overlayarea?

Viesturs
  • 7,895

1 Answers1

1

Here is a (admittedly somewhat hacky) style, based on this post, that records the bounding box of a picture, which requires an identifier like A. The key recycle bounding box=<identifier> will record the bounding box to the aux file such that it gets restored in the second run.

\documentclass{beamer}
\usepackage{tikz}
\makeatletter
\tikzset{recycle bounding box/.style={%
execute at end picture={%
\immediate\write\@mainaux{\xdef\string\figbb@#1{%
(\the\pgf@picminx,\the\pgf@picminy) rectangle (\the\pgf@picmaxx,\the\pgf@picmaxy)}\relax}},
execute at begin picture={%
\ifcsname figbb@#1\endcsname
 \edef\figbb{\csname figbb@#1\endcsname}
 \path \figbb;
\fi}}}
\makeatother
\begin{document}
\begin{frame}[t]
      \begin{tikzpicture}[recycle bounding box=A]%<- A is an identifier
        \draw[red, very thick](0, 0) -- (3, 0);
        \only<1>{
          \draw(-1, 1) -- (2, 1);
        }
        \only<2>{
          \draw(-2, 2) -- (1, 2);
        }
      \end{tikzpicture}
  \end{frame}
\end{document}

enter image description here

If you have several pictures the bounding boxes of which you want to record, you need to give each of them a unique identifier. In this regard this works like the eqparbox package. Like in eqparbox you need to run twice. (Note to myself: this style will be very useful for animations.)

You can also draw the picture in the overlay mode

\documentclass{beamer}
\usepackage{tikz}
\begin{document}
\begin{frame}
      \begin{tikzpicture}[overlay,remember picture,shift={(current page.center)}]
        \draw[red, very thick](0, 0) -- (3, 0);
        \only<1>{
          \draw(-1, 1) -- (2, 1);
        }
        \only<2>{
          \draw(-2, 2) -- (1, 2);
        }
      \end{tikzpicture}
  \end{frame}
\end{document}

enter image description here

The problem with this approach is that we need to add the shift by hand. Another reading of the question is answered by

use \path[use as bounding box] ....,

as in

\documentclass{beamer}
\usepackage{tikz}
\begin{document}
\begin{frame}
    \begin{overlayarea}{\linewidth}{0.9\paperheight}
      \centering
      \begin{tikzpicture}
        \path[use as bounding box] (-4,-2) rectangle (4,3);
        \draw[red, very thick](0, 0) -- (3, 0);
        \only<1>{
          \draw(-1, 1) -- (2, 1);
        }
        \only<2>{
          \draw(-2, 2) -- (1, 2);
        }
      \end{tikzpicture}
    \end{overlayarea}
  \end{frame}
\end{document}

enter image description here

The downside is that we need to fix the bounding box by hand. This is what gets avoided by the hack at the beginning of the answer.

I personally use the overlay-beamer-styles library. That way you just make the paths invisible but keep them in such that the bounding box does not change.

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{overlay-beamer-styles}
\begin{document}
\begin{frame}
    \begin{overlayarea}{\linewidth}{0.9\paperheight}
      \centering
      \begin{tikzpicture}
        \draw[red, very thick](0, 0) -- (3, 0);
          \draw[visible on=<1>](-1, 1) -- (2, 1);
          \draw[visible on=<2>](-2, 2) -- (1, 2);
      \end{tikzpicture}
    \end{overlayarea}
  \end{frame}
\end{document}

enter image description here

You can introduce short cuts:

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{overlay-beamer-styles}
\begin{document}
\begin{frame}[t]
\frametitle{Some title}
      \centering% the number of # depends on whether or not you add these
      % definitions in the frame and whether or not your frame is `fragile`.
      \begin{tikzpicture}[vo/.style={visible on=<####1>}]
        \draw[red, very thick](0, 0) -- (3, 0);
          \draw[vo={1}](-1, 1) -- (2, 1);
          \draw[vo={2}](-2, 2) -- (1, 2);
      \end{tikzpicture}
\end{frame}
\end{document}
  • My actual figure is much more complicated. Adding visible on= to each element will be very tiresome. – Viesturs May 02 '20 at 22:06
  • @Viesturs I added a completely new answer that records the bounding box such that you can keep your syntax. –  May 02 '20 at 23:05