I have as many as 15-20 overlays within a frame
. I am trying to highlight certain states in a state diagram. The problem is sometimes I would want to add an overlay, say between 5 and 6. I would need to increase the counter of all the overlays following 6 which can be quite annoying. I considered numbering overlays in multiples of 5 just so that I can insert an overlay later. However, each number would result in a new slide which is highly undesirable. Another solution is creating a separate frame. Is there a better way to handle this? Am I missing something obvious?
3 Answers
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}
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))
-
Great idea ! I adapted your code to my needs, accepting constructs like <article:0|2-4,7-9>, ensuring we do not miss implicit overlays (esp. number 1) and some userfriendlyness when dealing with large source files : framagit.org/ysalmon/includes/-/blob/master/latex/…– ysalmonOct 26, 2020 at 21:41
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.)
-
4You can further optimize by adding
[<+->]
after\begin{itemize}
. Then you don't need the overlay specifications on each\item
. Jun 6, 2013 at 12:22 -
<-+>
syntax which automatically increments the overlay number?