How to insert overlays in latex beamer

Here's an example of using incremental overlay specifications with offsets.

\documentclass{beamer}
\begin{document}
\begin{frame}[label=integral-of-x]{Example: Integral of $f(x) =x$}
\begin{example}<+->
Find $\int_0^3 x\,dx$.
\end{example}
\begin{solution}<+->
\action<.->{For any $n$ we have $\alert<.(5)>{\Delta x = \frac{3}{n}}$ and for each $i$ between $0$ and $n$, $\alert<.(4)>{x_i = \frac{3i}{n}}$.}
\action<+->{For each $i$, take $x_i$ to represent $f$ on the $i$th interval.}
\action<+->{So}
\begin{align*}
    \action<.->{\int_0^3 x\,dx = \lim_{n\to\infty} R_n }
        \action<+->{&= \lim_{n\to\infty} \sum_{i=1}^n \alert<.(1)>{f(x_i)}\,\alert<.(2)>{\Delta x}}
        \action<+->{ = \lim_{n\to\infty}\sum_{i=1}^n 
            \alert<.>{\left(\frac{\alert<.(2)>{3}i}{\alert<.(2)>{n}}\right)}
            \alert<+>{\left(\frac{\alert<.(1)>{3}}{\alert<.(1)>{n}}\right) }\\}
        \action<+->{&= \lim_{n\to\infty}\alert<.>{\frac{9}{n^2}} \alert<.(1)>{\sum_{i=1}^n i}}
        \action<+->{ = \alert<.(1)>{\lim_{n\to\infty}}\frac{9}{\alert<.(1)>{n^2}} 
            \cdot \alert<.>{\frac{\alert<.(1)>{n(n+1)}}{2}}}
        \action<+->{= \frac{9}{2}\alert<.>{\cdot 1}}
\end{align*}
\end{solution}
\end{frame}
\end{document}

sample code output

Basically, <+-> means increment the pause count and apply this from that pause count onwards. <.-> means from the current pause count onwards (doesn't really do anything, but useful to be organized). And things like <.(5)> mean at the current pause count plus five. So you can insert things before or after without having to change pause counts explicitly. Of course, if you refer to overlays with <.> and <.(5)> and you want to insert something in between, you will need to change <.(5)> to <.(6)> or something similar.

My workflow in creating complex sequences like this is usually to map it out on paper. I will write down what should come on, go off, or change at each step. From there it's a matter of guess-and-check. The \includeonlyframes preamble command allows you to focus on one frame while developing.


I think there are cases where incremental overlays are not sufficient. For example, the frame can uncover a diagram and at the same time display comments somewhere else:

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

\begin{document}
\begin{frame}
\begin{tikzpicture}[framed]
    \onslide<1->{\node[red] (r) {Red};}
    \onslide<2->{\node[blue, below of = r] {Blue};}
\end{tikzpicture}\\
\only<1>{Red node comment}
\only<2>{Blue node comment}
\end{frame}
\end{document}

In this case we might want to insert a new node, say green, to appear between the red and blue. As far as I know, the only solution would be to insert

\onslide<2->{\node[green, right of = r] {Green};}

between the red and blue and then manually increment all the affected overlay specifications (i.e. add 1 to everything greater or equal to two). This could be very tedious in case of complex diagrams. Perhaps a neater way would be if beamer supported fractional slide numbers, so that we could insert something like

\onslide<1.5->{\node[green, right of = r] {Green};}

I recently had to modify a larger diagram and after spending some time re-numbering I wrote a simple python script which converts such fractional specifications into equivalent ones using only integers. The script below reads a text file (given in the first argument) containing a single frame with fractional overlays and outputs an equivalent valid beamer frame. It is very crude (for example doesn't work if an overlay specification is broken across two lines) but could serve as a good starting point.

import re
import sys

p = re.compile("<(([0-9]+(\.[0-9]+)?)(-([0-9]+(\.[0-9]+)?)?)?)>")

def extract(s):

    ret = set()
    for r in [m[0] for m in p.findall(s)]:
        ret = ret.union(set([float(x) for x in r.split('-') if x]))
    return ret

def sub(s, newi):
    for m in [m for m in p.finditer(s)]:
        for r in [m.regs[2], m.regs[5]]:
            if r[0] < 0: continue
            s = s[:r[0]] + str(newi[float(s[r[0]:r[1]])]) + s[r[1]:]
    return s


f = open(sys.argv[1], "r+")
ls = [l for l in f]
xs = set.union(*[extract(l) for l in ls])
newi = dict(zip(sorted(xs), range(len(xs)+1)[1:]))
for l in ls:
    sys.stdout.write(sub(l, newi))

From the beamer manual (you can read it with texdoc beamer), the following overlay

\begin{itemize}
\item<1-> Apple
\item<2-> Peach
\item<3-> Plum
\item<4-> Orange
\end{itemize}

is equal to

\begin{itemize}
\item<+-> Apple
\item<+-> Peach
\item<+-> Plum
\item<+-> Orange
\end{itemize}

In the case of a not sequential order, you can write a new command and use \setcounter and \addtocounter. (Sorry for not point a example, I couldn't find one.)