我正在尝试制作一个动画来展示如何找到一小串数字的中位数。由于我想将其合并到演示文稿中,所以我使用了 beamer 框架,但我愿意接受其他替代方案。我使用了 tikz,因为我通常喜欢 tikz 图片的输出。
我遇到了一些困难。我一个接一个地构建框架,因此这种方法很繁琐,而且扩展性不好。我尝试了 for 循环,但没有成功。由于我对 tikz 不熟悉,所以框会移动一点,数字也会错位。如果能修复抖动并有一个循环,就可以为其他数字集生成动画,那就太好了。
我还计划在最后添加一个小气泡,以解释偶数列表的中位数按照惯例被认为是“中间”最后两个数字的平均值,但这仍然有待完成。现在我不认为我的动画太丑了,但我也不认为它太漂亮了,所以如果你看到明显的改进,请随意使用你的审美判断。
因此,我们得到一个排序列表,并逐个消除极值,直到:
我的蹩脚代码:
\PassOptionsToPackage{usenames,dvipsnames,svgnames}{xcolor}
\documentclass[20pt]{beamer}
\setbeamertemplate{navigation symbols}{}
\setbeamertemplate{headline}{}
\setbeamertemplate{footline}{}
\usepackage{tikz}
\usetikzlibrary{shapes.misc}
\newcommand{\crossout}[1]{\raisebox{-0.5mm}{%
\tikz{\draw(0,0) node[anchor=west, inner sep=0pt](cross){#1};
\draw[cross out, red, line width=2pt](cross.north west) -- (cross.south east);
\draw[cross out, red, line width=2pt](cross.south west) -- (cross.north east);
}}}
\newcommand\selected[1]{\raisebox{-0.5mm}{
\tikz[baseline=(center.base)] \node[draw,rectangle,blue,line width=2pt,inner sep=2pt] (center){#1};
}}
\usepackage{mathtools}
\usepackage{empheq}
\usepackage[many]{tcolorbox}
\tcbset{highlight math style={enhanced,
colframe=red!60!black,colback=yellow!50!white,arc=4pt,boxrule=1pt,
}}
\newcommand{\s}{\hspace{10pt}}
\begin{document}
\begin{frame}
\begin{empheq}[box=\tcbhighmath]{align*}
1 \s 1 \s 2 \s 2 \s 3 \s 3 \s 5 \s 6 \s 6 \s 8 \s 8 \s 9
\end{empheq}
\end{frame}
\begin{frame}
\begin{empheq}[box=\tcbhighmath]{align*}
\crossout{1} \s 1 \s 2 \s 2 \s 3 \s 3 \s 5 \s 6 \s 6 \s 8 \s 8 \s \crossout{9}
\end{empheq}
\end{frame}
\begin{frame}
\begin{empheq}[box=\tcbhighmath]{align*}
\crossout{1} \s \crossout{1} \s 2 \s 2 \s 3 \s 3 \s 5 \s 6 \s 6 \s 8 \s \crossout{8} \s \crossout{9}
\end{empheq}
\end{frame}
\begin{frame}
\begin{empheq}[box=\tcbhighmath]{align*}
\crossout{1} \s \crossout{1} \s \crossout{2} \s 2 \s 3 \s 3 \s 5 \s 6 \s 6 \s \crossout{8} \s \crossout{8} \s \crossout{9}
\end{empheq}
\end{frame}
\begin{frame}
\begin{empheq}[box=\tcbhighmath]{align*}
\crossout{1} \s \crossout{1} \s \crossout{2} \s \crossout{2} \s 3 \s 3 \s 5 \s 6 \s \crossout{6} \s \crossout{8} \s \crossout{8} \s \crossout{9}
\end{empheq}
\end{frame}
\begin{frame}
\begin{empheq}[box=\tcbhighmath]{align*}
\crossout{1} \s \crossout{1} \s \crossout{2} \s \crossout{2} \s \crossout{3} \s 3 \s 5 \s \crossout{6} \s \crossout{6} \s \crossout{8} \s \crossout{8} \s \crossout{9}
\end{empheq}
\end{frame}
\begin{frame}
\begin{empheq}[box=\tcbhighmath]{align*}
\crossout{1} \s \crossout{1} \s \crossout{2} \s \crossout{2} \s \crossout{3} \selected{3 \s 5} \crossout{6} \s \crossout{6} \s \crossout{8} \s \crossout{8} \s \crossout{9}
\end{empheq}
\end{frame}
\end{document}
后记
稍作调整麦克风的优秀答案。我发现加载makecell
包以允许在节点内换行很有用:
\usepackage{makecell}
...
\makecell[c]{%
by convention, \\
the median is: \\
$\dfrac{3+5}{2} = 4$}
我还在节点内添加了使上方文本居中的选项align=center
。最后选择了xframe.south
“调出绝对指针”。
我还发现我可以将标准 beamer 字体保留为 11pt,以使 frametitle 保持标准大小,同时控制 tikzpictures 中的字体大小,例如\tikzset{font={\fontsize{20pt}{30}\selectfont}}
。没什么好写的,但这里是为了记录。
答案1
在此解决方案中,方框使用 TikZ 绘制,这可以防止其改变大小。该命令\crossoutframes
将生成所有帧,最后一帧带有气泡。
参数:
- (可选,显示默认值)
- xnum distance=20pt:数字之间的距离(中心到中心)
- xnum count=12: 列表中的数字数量
- xnum steps=5: 从左边和右边划掉多少个数字
- 逗号分隔的数字列表
- 气泡的文本
由此\crossoutframes{1,1,2,2,3,3,5,6,6,8,8,9}{by convention}
产生(最后一帧)
或者\crossoutframes[xnum distance=15pt,xnum count=15,xnum steps=6]{1,1,2,2,3,3,4,5,5,6,6,8,8,9,9}{what now?}
(奇数个数字)
代码:
\PassOptionsToPackage{usenames,dvipsnames,svgnames}{xcolor}
\documentclass[20pt]{beamer}
\setbeamertemplate{navigation symbols}{}
\setbeamertemplate{headline}{}
\setbeamertemplate{footline}{}
\usepackage{tikz}
\usetikzlibrary{shapes.misc}
% for bubble
\usetikzlibrary{shapes.callouts}
% for frame around last two numbers
\usetikzlibrary{fit}
% some parameters
\tikzset{%
% distance between numbers, center to center
xnum distance/.store in=\xnumdistance,
% number of numbers in list
xnum count/.store in=\xnumcount,
% how many numbers to cross out from left and right
xnum steps/.store in=\xnumsteps
}
\newcommand{\crossoutframes}[3][xnum distance=20pt,xnum count=12,xnum steps=5]{%
% setup
\tikzset{#1}
% two runs more for framing last 2 numbers and bubble
\foreach \step in {0,1,...,\numexpr\xnumsteps+2}{%
\centering
\begin{frame}
\begin{tikzpicture}[x=1pt,y=1pt,line width=2pt,inner sep=0pt,outer sep=0pt,remember picture]
% frame (drawing manually prevents changing size)
% old: colframe colback arc boxrule
\filldraw[draw=red!60!black,fill=yellow!50!white,rounded corners=4pt,line width=1pt]
(0,20) -- (\xnumcount*\xnumdistance+\xnumdistance,20) -- (\xnumcount*\xnumdistance+\xnumdistance,-20) -- (0,-20) -- cycle;
% going through the numbers
\foreach \xnum [count=\i] in {#2}{%
% limit \step to 'xnum steps'
\ifnum\step>\xnumsteps\edef\step{\xnumsteps}\fi
% run 0: nothing crossed out
\ifnum\step=0\relax
% number not crossed out
\node[shape=cross out] (x\i) at (\i*\xnumdistance,0) {\xnum};
\else
%cross out or not, from left and right
\ifnum\i>\step
\ifnum\i<\numexpr\xnumcount-\step+1\relax
% number not crossed out
\node[shape=cross out] (x\i) at (\i*\xnumdistance,0) {\xnum};
\else
% number crossed out
\node[shape=cross out,draw=red] (x\i) at (\i*\xnumdistance,0) {\xnum};
\fi
\else
% number crossed out
\node[shape=cross out,draw=red] (x\i) at (\i*\xnumdistance,0) {\xnum};
\fi
\fi
}
% frame around last 2 numbers
\ifnum\step>\xnumsteps
\edef\firstnode{x\the\numexpr\xnumsteps+1}%
\edef\secondnode{x\the\numexpr\xnumcount-\xnumsteps}%
\node[draw=blue,inner sep=3pt,fit=(\firstnode) (\secondnode)] (xframe) {};
% \node[draw=blue,inner sep=3pt,fit=(x6) (x7)] (xframe) {};
\fi
\end{tikzpicture}
\hspace*{150pt}
\begin{tikzpicture}[line width=2pt,remember picture,overlay]
% bubble
\ifnum\step>\numexpr\xnumsteps+1\relax
\node[draw=green,inner sep=3pt,line join=round,
shape=ellipse callout,callout absolute pointer={(xframe.south east)}] {#3};
\fi
\end{tikzpicture}
\end{frame}
}
}
\begin{document}
\crossoutframes{1,1,2,2,3,3,5,6,6,8,8,9}{by convention}
\crossoutframes[xnum distance=15pt,xnum count=15,xnum steps=6]{1,1,2,2,3,3,4,5,5,6,6,8,8,9,9}{what now?}
\end{document}