4

How to use \foreach to simplify the following code.

I intentionally used tikzpictures without spaces between end and begin commands to display the graphs beside each other.

\documentclass{beamer}
\beamertemplatenavigationsymbolsempty
\usepackage{tikz}
\usepackage{pgfplots}
\begin{document}
\begin{frame}[t]
\frametitle{}
\begin{tikzpicture}[scale=.9, transform shape,linecolor/.style={ultra thick, green!40!black}]
\pgfmathsetmacro{\incrmnt}{.4}
\draw [thick,-latex](0,0) -- (3.5,0) node [pos=.5, black, xshift=0cm, yshift=-.5cm] {$\pi>0.5$} node [pos=.5, black, xshift=0cm, yshift=3.4cm] {Skewed to left} node [xshift=.2cm, yshift=0cm] { };
\draw [thick,-latex](0,0) -- (0,4);
\draw [linecolor] (\incrmnt*1,0) +(90:\incrmnt*1) -- +(-90:0);
\draw [linecolor] (\incrmnt*2,0) +(90:\incrmnt*2) -- +(-90:.0);
\draw [linecolor] (\incrmnt*3,0) +(90:\incrmnt*3) -- +(-90:.0);
\draw [linecolor] (\incrmnt*4,0) +(90:\incrmnt*4) -- +(-90:.0);
\draw [linecolor] (\incrmnt*5,0) +(90:\incrmnt*5) -- +(-90:.0);
\draw [linecolor] (\incrmnt*6,0) +(90:\incrmnt*6) -- +(-90:.0);
\draw [linecolor] (\incrmnt*7,0) +(90:\incrmnt*7) -- +(-90:.0);
\end{tikzpicture}
\begin{tikzpicture}[scale=.9, transform shape,linecolor/.style={ultra thick, green!40!black}]
\pgfmathsetmacro{\incrmnt}{.4}
\draw [thick,-latex](0,0) -- (3.5,0) node [pos=.5, black, xshift=0cm, yshift=-.5cm] {$\pi=0.5$} node [pos=.5, black, xshift=0cm, yshift=3.4cm] {Symmetric} node [xshift=.2cm, yshift=0cm] { };
\draw [thick,-latex](0,0) -- (0,4);
\draw [linecolor] (\incrmnt*1,0) +(90:\incrmnt*1) -- +(-90:0);
\draw [linecolor] (\incrmnt*2,0) +(90:\incrmnt*2) -- +(-90:.0);
\draw [linecolor] (\incrmnt*3,0) +(90:\incrmnt*3) -- +(-90:.0);
\draw [linecolor] (\incrmnt*4,0) +(90:\incrmnt*4) -- +(-90:.0);
\draw [linecolor] (\incrmnt*5,0) +(90:\incrmnt*3) -- +(-90:.0);
\draw [linecolor] (\incrmnt*6,0) +(90:\incrmnt*2) -- +(-90:.0);
\draw [linecolor] (\incrmnt*7,0) +(90:\incrmnt*1) -- +(-90:.0);
\end{tikzpicture}
\begin{tikzpicture}[scale=.9, transform shape,linecolor/.style={ultra thick, green!40!black}]
\pgfmathsetmacro{\incrmnt}{.4}
\draw [thick,-latex](0,0) -- (3.5,0) node [pos=.5, black, xshift=0cm, yshift=-.5cm] {$\pi<0.5$} node [pos=.5, black, xshift=0cm, yshift=3.4cm] {Skewed to right} node [xshift=.2cm, yshift=0cm] { };
\draw [thick,-latex](0,0) -- (0,4);
\draw [linecolor] (\incrmnt*1,0) +(90:\incrmnt*7) -- +(-90:0);
\draw [linecolor] (\incrmnt*2,0) +(90:\incrmnt*6) -- +(-90:.0);
\draw [linecolor] (\incrmnt*3,0) +(90:\incrmnt*5) -- +(-90:.0);
\draw [linecolor] (\incrmnt*4,0) +(90:\incrmnt*4) -- +(-90:.0);
\draw [linecolor] (\incrmnt*5,0) +(90:\incrmnt*3) -- +(-90:.0);
\draw [linecolor] (\incrmnt*6,0) +(90:\incrmnt*2) -- +(-90:.0);
\draw [linecolor] (\incrmnt*7,0) +(90:\incrmnt*1) -- +(-90:.0);
\end{tikzpicture}
\end{frame}
\end{document}

enter image description here

Using the answer of AndréC, I managed to use the following code

\begin{frame}[t]
\frametitle{}
\begin{tikzpicture}[scale=.9, transform shape,linecolor/.style={ultra thick, green!40!black}]
\pgfmathsetmacro{\incrmnt}{.4}
%Axis
\draw [thick,-latex](0,0) -- (\incrmnt*9,0) node [pos=.5, black, xshift=0cm, yshift=-.5cm] {$\pi>0.5$} node [pos=.5, black, xshift=0cm, yshift=3.4cm] {Skewed to left} node [xshift=.2cm, yshift=0cm] { };
\draw [thick,-latex](0,0) -- (0,4);

\draw [thick,-latex](\incrmnt*10,0) -- (\incrmnt*10*2,0) node [pos=.5, black, xshift=0cm, yshift=-.5cm] {$\pi=0.5$} node [pos=.5, black, xshift=0cm, yshift=3.4cm] {Symmetric} node [xshift=.2cm, yshift=0cm] { };
\draw [thick,-latex](\incrmnt*10,0) -- (\incrmnt*10,4);

\draw [thick,-latex](\incrmnt*10*2+\incrmnt,0) -- (\incrmnt*10*2+\incrmnt*10,0) node [pos=.5, black, xshift=0cm, yshift=-.5cm] {$\pi<0.5$} node [pos=.5, black, xshift=0cm, yshift=3.4cm] {Skewed to right} node [xshift=.2cm, yshift=0cm] { };
\draw [thick,-latex](\incrmnt*10*2+\incrmnt,0) -- (\incrmnt*10*2+\incrmnt,4);
%Curves
\foreach \y in {1,...,7}{\draw [ultra thick, linecolor] (\incrmnt*\y,0) +(90:\incrmnt*\y) -- +(-90:0);}

\begin{scope}[xshift=\incrmnt*10*30]
\foreach \y in {1,...,4}{\draw [ultra thick, linecolor] (\incrmnt*\y,0) +(90:\incrmnt*\y*1.5) -- +(-90:0);}
\foreach \y [evaluate=\y as \yy using int(8-\y)] in {5,...,7}{
\draw [linecolor] (\incrmnt*\y,0) +(90:\incrmnt*\yy*1.5) -- +(-90:0);
}
\end{scope}

\begin{scope}[xshift=\incrmnt*10*30*2]
\foreach \y [evaluate=\y as \yy using int(8-\y)] in {1,...,7}{
\draw [linecolor] (\incrmnt*\y,0) +(90:\incrmnt*\yy) -- +(-90:0);
}
\end{scope}
\end{tikzpicture}
\end{frame}

enter image description here

  • \foreach \x in {1,...,7}{ \draw [linecolor] (\x*\incrmnt,0) +(90:\x*\incrmnt) -- +(-90:0); } – Sigur Nov 2 '18 at 16:49
  • @ Sigur Thank you for your suggestion. But I could not produce the other 2 drawings by it. – Hany Nov 2 '18 at 18:38
10

The first and third graphs can use a foreach loop. As for the second, it is possible but not very useful. Personally, I find it too small to be really profitable.

Update:

Instead of placing 3 tikzpicture environments side by side without space, it is easier to fully use the power of TikZ and place the last two graphs in a scope environment and move it to the right.

\documentclass{beamer}
\beamertemplatenavigationsymbolsempty
\usepackage{tikz}
\usepackage{pgfplots}
\begin{document}
\begin{frame}[t]
\frametitle{}
\begin{tikzpicture}[scale=.9, transform shape,linecolor/.style={ultra thick, green!40!black}]
\pgfmathsetmacro{\incrmnt}{.4}
\draw [thick,-latex](0,0) -- (3.5,0) node [pos=.5, black, xshift=0cm, yshift=-.5cm] {$\pi>0.5$} node [pos=.5, black, xshift=0cm, yshift=3.4cm] {Skewed to left} node [xshift=.2cm, yshift=0cm] { };
\draw [thick,-latex](0,0) -- (0,4);
\foreach \y in {1,...,7}{
\draw [linecolor] (\incrmnt*\y,0) +(90:\incrmnt*\y) -- +(-90:0);
}

\begin{scope}[xshift=4cm]
\draw [thick,-latex](0,0) -- (3.5,0) node [pos=.5, black, xshift=0cm, yshift=-.5cm] {$\pi=0.5$} node [pos=.5, black, xshift=0cm, yshift=3.4cm] {Symmetric} node [xshift=.2cm, yshift=0cm] { };
\draw [thick,-latex](0,0) -- (0,4);
\draw [linecolor] (\incrmnt*1,0) +(90:\incrmnt*1) -- +(-90:0);
\draw [linecolor] (\incrmnt*2,0) +(90:\incrmnt*2) -- +(-90:.0);
\draw [linecolor] (\incrmnt*3,0) +(90:\incrmnt*3) -- +(-90:.0);
\draw [linecolor] (\incrmnt*4,0) +(90:\incrmnt*4) -- +(-90:.0);
\draw [linecolor] (\incrmnt*5,0) +(90:\incrmnt*3) -- +(-90:.0);
\draw [linecolor] (\incrmnt*6,0) +(90:\incrmnt*2) -- +(-90:.0);
\draw [linecolor] (\incrmnt*7,0) +(90:\incrmnt*1) -- +(-90:.0);
\end{scope}

\begin{scope}[xshift=8cm]
\draw [thick,-latex](0,0) -- (3.5,0) node [pos=.5, black, xshift=0cm, yshift=-.5cm] {$\pi<0.5$} node [pos=.5, black, xshift=0cm, yshift=3.4cm] {Skewed to right} node [xshift=.2cm, yshift=0cm] { };
\draw [thick,-latex](0,0) -- (0,4);
\foreach \y [evaluate=\y as \yy using int(8-\y)] in {1,...,7}{
\draw [linecolor] (\incrmnt*\y,0) +(90:\incrmnt*\yy) -- +(-90:0);
}
\end{scope}
\end{tikzpicture}
\end{frame}
\end{document}

graphes

  • 1
    @Hany I improved the code by using only one tikzpicture environment and two scope environments. – AndréC Nov 2 '18 at 17:15
  • @ AndréC Thank you very much for your answer and its update. I managed to draw the middle one by combining both of your codes for 1 and 2. \begin{scope}[xshift=\incrmnt*10*30] \foreach \y in {1,...,4}{\draw [ultra thick, linecolor] (\incrmnt*\y,0) +(90:\incrmnt*\y*1.5) -- +(-90:0);} \foreach \y [evaluate=\y as \yy using int(8-\y)] in {5,...,7}{ \draw [linecolor] (\incrmnt*\y,0) +(90:\incrmnt*\yy*1.5) -- +(-90:0); } \end{scope} – Hany Nov 2 '18 at 18:24
  • @ AndréC Please refer to my edited post. Thank you very much. – Hany Nov 2 '18 at 18:32
  • 1
    @Hany Yes, it is feasible, but the question that needs to be asked is: Does it make the code easier to read? Is making two small loops easier than a simple copy and paste? – AndréC Nov 2 '18 at 18:39
  • @ AndréC It does not make the code easier to read. But it is my trial to understand your line of thinking and using it. Thank you very much for your time and effort. I appreciate it very much. – Hany Nov 2 '18 at 18:42
7

An alternative to AndréC's nice answer, inspired by pgfplots loading behavior. ;-) It has not a single visible loop, but is nonetheless shorter. ;-)

\documentclass{beamer}
\beamertemplatenavigationsymbolsempty
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\usepgfplotslibrary{groupplots}
\begin{document}
\begin{frame}[t]
\frametitle{\emph{Now} I know why you're always loading \texttt{pgfplots} ;-)}
\begin{tikzpicture}[scale=.9, transform shape,linecolor/.style={ultra thick, green!40!black}]
\begin{groupplot}[group style={group size=3 by
2, x descriptions at=edge bottom,},xmin=-0.5,xmax=7.5,ymax=8,height=4cm,width=5cm,
axis lines=left,title style={font=\small,anchor=north}]
\nextgroupplot[xtick={},ytick=\empty,
xlabel={$\pi>0.5$},title={Skewed to the left}]
\addplot [samples at={0,...,7},ycomb,no marks,linecolor] {x};
\nextgroupplot[xtick=\empty,ytick=\empty,
xlabel={$\pi=0.5$},title={Symmetric}]
\addplot [samples at={0,...,7},ycomb,no marks,linecolor]
{x+ifthenelse(x>3,7-2*x,0)};
\nextgroupplot[xtick=\empty,ytick=\empty,
xlabel={$\pi<0.5$},title={Skewed to the right}]
\addplot [samples at={0,...,7},ycomb,no marks,linecolor] {7-x};
\end{groupplot}
\end{tikzpicture}
\end{frame}
\end{document}

enter image description here

  • @ marmot Thank you very much for your time and effort. – Hany Nov 2 '18 at 18:26

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.