Some LaTeX Gems - Part 1: TikZ, Loops and more

Tangents

This logo means that the blog post is about something I have found interesting, but does not apply directly to the exact purpose of this blog.

Note: These commands have been tested in pdflatex. I am not sure if they work in other distributions.

Over the past couple of months, I have been assisting with editing some papers and also doing some projects in LaTeX. Seeing other peoples’ code has taught me some interesting things. Here are a few of them.

Arrays, Lists, and Loops

Indeed, it is possible to write loops in LaTeX, with a few limitations. I have used this in some of the following ways

  1. creating a perfectly aligned bubble answer sheet for scoring by a desktop scanner.
  2. constructing midterms using a different dataset (form) for each student.
  3. creating sheets of business cards for our consulting center / mail merge.

Some other ways arrays and loops can be used with some clever programming:

  • creating multiple forms of an exam using item from different files.
  • reports such as rosters, invoices, pre-printed forms, etc.

Arrays. To create an array in LaTeX, you will need the arrayjob package that can be downloaded from here. Then, to create the array we use the command \newarray\ArrayName where ArrayName is the name of the array we want to create. Then, we use the \readarray{arrayname}{elements separated by &} to actually populate the array with entries. The entries must be separated by ampersands (&) though. If we want to split entries across lines, we just end each line with a percent sign (%).

\usepackage{arrayjob}
.
.
.
\newarray\Datasets
\readarray{Datasets}{%
alabama1.txt &%
alabama2.txt &%
alaska1.txt}
%Do something with the array using a loop.

Lists. [just found today] We can also create a list in LaTeX, and this is actually easier than creating an array with arrayjob! We simply use the \def command followed by the name of the list and its arguments in {}.

\def\Datasets{alabama1.txt, alabama2.txt, alaska1.txt}

Loops. We can iterate through the array or list using a foreach loop from the TikZ package (surprisingly). There are actually a couple of different ways to do this, such as using a counter with a loop. Here I am just going to use the simplest method.

As an example, consider some pseudocode to create several midterms, all containing the same questions, but each using a different dataset file. (This is a real example) To do this, we must wrap all of the code that defines the midterm page within the loop, so that the entire midterm is generated on each iteration of the loop, and then use \newpage to force a new page for the next iteration.

\foreach \dataset in \Datasets
{
   \newpage %force a new page for each exam.
   % a bunch of header stuff introducing the exam.

   \noindent Please access your data set in \texttt{R} using: \\
   \footnotesize
   \texttt{a = read.table("http://.../\dataset", header=TRUE)} \\
}

Or, using an array we can access the jth element:

\foreach \j in {1,...,3}
{
   \newpage %force a new page for each exam.
   % a bunch of header stuff introducing the exam.

   \noindent Please access your data set in \texttt{R} using: \\
   \footnotesize
   \texttt{a = read.table("http://.../\Datasets(\j)", header=TRUE)} \\
}

Figure Directories and Extensions

For graphics, we can tell LaTeX to look in a particular directory to find our graphics files.

\graphicspath{{Figures/}}

Then, it is no longer necessary to reference the directory Figures/ in the filename passed to \includegraphics. For more information about \graphicspath, check here.

A matter of fact, we can even tell LaTeX what extensions to expect for our graphics files. Below, if we give LaTeX a graphic’s filename without the extension, it will search for files of the given types, in the order that they are passed to the command:

%using the command below, as well as the \graphicspath trick,
\DeclareGraphicsExtensions{.pdf,.png,.jpg}
%we can load a graphic using the following:
\begin{figure}
\includegraphics[width=3in]{myfigure} %no directory and no extension
\end{figure}

Alternate Directories

Not all of your LaTeX code needs to be in the same file. In fact, it is much better to spread out your code into logical units such as sections and chapters into different directories. Then, create one master file that references the files for each section or chapter.

In the main file, we just call \input and pass the path to the corresponding file as an argument.

Suppose I have 5 chapters, and each chapter has its own directory containing a LaTeX file and some graphics. We can combine all of these chapters into one document as follows:

\begin{document}
     \input{chapter1/chapter1code}
     \input{chapter2/chapter2code}
     \input{chapter3/chapter3code}
     \input{chapter4/chapter4code}
     \input{chapter5/chapter5code}
\end{document}

Some Plots

TikZ is an awesome syntax for drawing vector graphics in LaTeX by Till Tantau. It is set of high-level TeX macros for PGF. I must warn readers that this section is for hardcore LaTeX folks because a lot of the syntax is obscure and takes some getting used to. I apologize if my explanation is not incredibly clear…I am new to this as well.

I wanted to plot the piecewise function induced by the following discrete probability distribution. The exercise for the students was to generate random numbers from the following probability distribution:

Probdist

First, we open the tikzpicture environment. Since random uniform numbers range from 0 to 1, the u axis will go from 0 to 1. That is, the domain is from 0 to 1, so we specify domain=0:1. We will also want to magnify the image a bit so we set xscale=2, yscale=2.

\begin{center}
\begin{tikzpicture}[domain=0:1,xscale=2,yscale=2]
\foreach \y/\ytext in {-1/,-0.75/,-0.5/-1,-.25/,0.25/,0.5/1,0.75/,1/2,1.25/,1.5/}
     \draw[shift={(0,\y)},thick,color=gray!40,dashed] (2.5,0) -- (0,0) node[color=black,left] {\scriptsize $\ytext$};
%Plot the vertical lines.
\foreach \x/\xtext in {0.25/0.1,0.5/,0.75/0.3,1/,1.25/0.5,1.5/,1.75/0.7,2/,2.25/0.9,2.5/}
     \draw[shift={(\x,0)},thick,color=gray!40,dashed] (0,-1) -- (0,1.5);% node[color=black,below] {\scriptsize $\xtext$};
%Plot faux vertical lines just so we can label the x axis ticks.
\foreach \x/\xtext in {0.25/0.1, 0.75/0.3, 1.25/0.5, 1.75/0.7, 2.25/0.9}
     \draw[shift={(\x,0)},thick,color=gray!0] (0,0) -- (0,0) node[color=black,below]{\scriptsize $\xtext$};

\draw[->] node[left] {\scriptsize $0$} (0,0) -- (2.5,0)
	node[below right] {$u$};
\draw[<->] (0,-1) -- (0,1.5)
	node[left] {$x_k$};
\draw[line width=0.5mm] (0,-0.5) -- (0.25,-0.5); %-1
\draw[line width=0.5mm] (0.25,0) -- (1,0); %0
\draw[line width=0.5mm] (1,1) -- (2.5,1); %2
\draw[fill=white] (0,-0.5) circle (0.25mm);
\draw[fill=black] (0.25,-0.5) circle (0.25mm);
\draw[fill=white] (0.25,0) circle (0.25mm);
\draw[fill=black] (1,0) circle (0.25mm);
\draw[fill=white] (1,1) circle (0.25mm);
\draw[fill=black] (2.5,1) circle (0.25mm);
\end{tikzpicture}
\end{center}

In this plot, each 0.25 units on the u axis represents 0.1, and each 0.25 units on the x_k axis represents 0.5 units.

Next, we generate the gray grid. There is a command in TikZ called \grid that constructs a grid, but I am choosing not to use it for reasons I will explain a bit later. In line 4, we use a foreach loop to generate a series of horizontal lines. This is a special foreach loop in that it uses two counters, separated by a slash (/). The first number will be used as a plotting coordinate (in user defined graphics units) and the second number will serve as a tick label on the axis. These values form a key/value pair if you will.

On line 5 we use the \draw command to actually draw the lines. The shift parameter tells TikZ to move the pen to a new location (in this case, (0,\y)) to begin drawing. We specify that we want thick, dashed lines that are colored gray with 40% opacity. Then, with respect to the pen’s location, we draw a line from (2.5, 0) to (0, 0), where (0, 0) is the location of then pen before drawing the line.

Nodes allow us to annotate objects that we draw, and do other cool things. After drawing the line, we want to put a node to the left of the line, and the node is going to contain the text specified in the foreach loop. In this particular example, I want to label the tick marks on the axis. We do this by specifying a node to the left of the line, containing the text in the braces. Since the grid lines are gray, we must explicitly specify that we want the tick labels to be black. Note that the line was drawn from the right endpoint to the left endpoint. If we want to draw the line from left to right, we would place the node statement before we specify the coordinates for the line. Note that I did not include a line at 0. This is for aesthetic purposes so that the grid line does not blend with the u axis line.

On lines 6 and 7 I do the same for the vertical lines. On lines 9 and 10, I create some fake vertical lines that all start at (0, u), so I can use the nodes feature to annotate the u axis. If there is a better way to do this, please comment! This time, I pass below as a parameter to node because I want the annotations to print below the line I just drew.

Next, on lines 12-15 I draw the axis. Using -> tells TikZ that the right endpoint of the u axis should have an arrow and < -> draws an arrow on both endpoints for the x_k axis. On line 12 I specify that a node is to be drawn to the left of the line that is about the drawn. The node should contain the number 0 denoting the origin. Then, I draw the axis from (0,0) to (2.5,0) and then draw a node containing the label u to the bottom and right of the axis we just drew. Lines 14 and 15 are similar, but for the x_k axis.

Then we draw the actual function (three lines) on lines 16-18 with respect to the user’s coordinate system. We want to make the lines a little thicker than the grid so that they will stand out. I accomplished this by passing line width=0.5mm as an option to \draw. On lines 19-24 We draw the little circles that denote inclusion/exclusion in the domain for each piece of the function. First we specify the fill color, white for exclusion (an open dot), and black for inclusion (a solid dot). Then we specify where the pen should move to, and tell TikZ to draw a circle with a particular radius (0.25mm).

The result:

Piecewise

I’m out of breath.

You can also plot functions symbolically if you have gnuplot installed. You can download gnuplot for Linux and Windows systems here, and for Mac here.

There is a ton more to learn about TikZ syntax. Check out the fairly comprehensive PGF/TikZ manual or the PGF/TikZ gallery at TeXample.net. There is not much out there in terms of documentation yet, but this package is surely going to blow up on the Internet, as R and GRASS GIS have.

3 comments to Some LaTeX Gems – Part 1: TikZ, Loops and more

  • With respect to your “Arrays, Lists, and Loops” task, have you checked the datatool package? I found it very useful for typesetting our conference program (see PDF file). Information about participants or abstracts were saved outside the TeX document (as csv file) and datatool provides commands to read/import this kind of data (e.g., “Participants”, “Abstracts”).

    • Thank you!!! This package looks awesome. When I get it running, I’ll write a Part 2.

      As much as I use, and love, LaTeX, it’s not as easy to find packages or install them, as it is in R and Python.

  • Sarah Miller

    The part about lists/arrays is just what I needed to do some simple table lookups. Thank you.

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>