Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

As a Teaching Assistant for a class, I am trying to draw a seating chart for the professor. The seating chart will have a photo of each student, the student's name, and where the student is sitting in the lecture room. I need to produce two seating charts:

  1. A blank seating chart where a rectangle represents each chair, for students to fill in their names where they are seated.
  2. A seating chart with students' names and photos.

Before attempting to draw a seating chart for the 80+ seats in the lecture hall, I am working on a smaller example with 11 seats. Currently, the code I use to draw the blank seating chart and the output looks like the following:

\documentclass[10pt]{article}

\usepackage[margin=0in,paperwidth=17in, paperheight=11in]{geometry}

\usepackage{tikz}

% Usage: \student{x coord}{y coord}{name}{picture file}
%\newcommand{\student}[4]{%
%  \node[anchor=base,inner sep=0,
%      label={[text width=20mm,align=center]below:#3}] at (#1,#2)
%      {\includegraphics[width=17mm]{#4}};%
%}

% Draw an empty box for each chair
\newcommand{\student}[4]{
  \node[anchor=base,shape=rectangle,draw,
      minimum width=17mm,minimum height=22mm]
      at (#1,#2) {};
}

\begin{document}

\begin{center}
\begin{tikzpicture}
  \draw[white] (0,0) -- (43.1,0) -- (43.1,27.9) -- (0,27.9) -- (0,0);

  \draw (5,5) -- (10,15);
  \draw (12,18) -- (31,18);
  \draw (38,5) -- (33,15);

  \student{4}{7}{George Washington}{empty-face.png};
  \student{5.5}{10}{John Adams}{empty-face.png};
  \student{7}{13}{Thomas Jefferson}{empty-face.png};

  \student{12.5}{20}{James Madison}{empty-face.png};
  \student{17}{20}{James Monroe}{empty-face.png};
  \student{21.5}{20}{John Quincy Adams}{empty-face.png};
  \student{26}{20}{Andrew Jackson}{empty-face.png};
  \student{30.5}{20}{Martin Van Buren}{empty-face.png};

  \student{36}{13}{William Henry Harrison}{empty-face.png};
  \student{37.5}{10}{John Tyler}{empty-face.png};
  \student{39}{7}{James K Polk}{empty-face.png};

\end{tikzpicture}
\end{center}

\end{document}

Blank seating chart output

And the code for the seating chart with people's names and photos is very similar:

\documentclass[10pt]{article}

\usepackage[margin=0in,paperwidth=17in, paperheight=11in]{geometry}

\usepackage{tikz}

% Usage: \student{x coord}{y coord}{name}{picture file}
\newcommand{\student}[4]{%
  \node[anchor=base,inner sep=0,
      label={[text width=20mm,align=center]below:#3}] at (#1,#2)
      {\includegraphics[width=17mm]{#4}};%
}

\begin{document}

\begin{center}
\begin{tikzpicture}
  \draw[white] (0,0) -- (43.1,0) -- (43.1,27.9) -- (0,27.9) -- (0,0);

  \draw[line width=5mm] (5,5) -- (10,15);
  \draw[line width=5mm] (12,18) -- (31,18);
  \draw[line width=5mm] (38,5) -- (33,15);

  \student{4}{7}{George Washington}{empty-face.png};
  \student{5.5}{10}{John Adams}{empty-face.png};
  \student{7}{13}{Thomas Jefferson}{empty-face.png};

  \student{12.5}{20}{James Madison}{empty-face.png};
  \student{17}{20}{James Monroe}{empty-face.png};
  \student{21.5}{20}{John Quincy Adams}{empty-face.png};
  \student{26}{20}{Andrew Jackson}{empty-face.png};
  \student{30.5}{20}{Martin Van Buren}{empty-face.png};

  \student{36}{13}{William Henry Harrison}{empty-face.png};
  \student{37.5}{10}{John Tyler}{empty-face.png};
  \student{39}{7}{James K Polk}{empty-face.png};

\end{tikzpicture}
\end{center}

\end{document}

Seating chart with names and photos

In my prior post: Aligning image and text in new command in TikZ, Peter Grill recommended using a \foreach loop to plot multiple students. This is a great idea! Unfortunately, the seating in the lecture room is not regular. In fact, there are ~80 seats behind the desks which are shown in the image below:Layout of desks of the lecture hall

My question is the following.

What I would like to do is to define a list of locations:

\newcommand{\ListOfSeats}{
  (4,7) (5.5,10) (7,13) (12.5,20) (17,20)
  (21.5,20) (26,20) (30.5,20) (36,13) (37.5,10) (39,7)
}

and a list of students' names and photos

\newcommand{\ListOfStudents}{
  (George Washington, george-washington.jpg)
  (John Adams, john-adams.jpg)
  (Thomas Jefferson, thomas-jefferson.jpg)
  ...
}

Is there a way to then use a single \foreach loop to draw all the 80 seats, and all the 80 students with their names and photos?

Thanks for reading to the end, this was a long question but I hope you found it interesting!

share|improve this question
    
Are you open for small changes to the syntax ({} instead of (), / instead of ,)? It would also be easier to use one list with entries like: George Washington/george-washington.jpg/4/7 –  Qrrbrbirlbel Feb 17 '13 at 3:03
    
Definitely! I was just the syntax which seemed most natural to me, but would be happy to adopt whatever syntax works. –  I Like to Code Feb 17 '13 at 3:07
    
What about introducing seat numbering? I think this would make it easier to enter the data from the (fill-out) blank chart. –  Sašo Živanović Feb 17 '13 at 3:23
    
That's a great idea! –  I Like to Code Feb 17 '13 at 3:28
    
Is the syntax George Washington, george-washington.jpg common to all the students and their images? If yes, then we don't need the 2 comma-separated elements: 1 will suffice. –  Ahmed Musa Feb 17 '13 at 6:55
add comment

2 Answers

up vote 6 down vote accepted

Easy To Code

As described in my comment, the easiest solution to code would be one list, one foreach and four variables separated by /.

Do not introduce any spaces in the second part (the one containing the file name).

If name or file name contains a , enclose the whole variable in { } braces, e.g.

{Sir, St. Comma}/{sir,-st.-comma.jpg}/0/0

Code

\documentclass[10pt]{article}
\usepackage[margin=0in,paperwidth=17in, paperheight=11in]{geometry}

\usepackage{tikz}

% Usage: \student{x coord}{y coord}{name}{picture file}
\newcommand{\student}[4]{%
  \node[anchor=base,inner sep=0,
      label={[text width=20mm,align=center]below:#3}] at (#1,#2)
      {\includegraphics[width=17mm]{#4}};%
}

\newcommand*{\ListOfStudents}{%
    George Washington     /example-image-10x16.jpg/ 4  / 7,
    John Adams            /example-image-10x16.jpg/ 5.5/10,
    Thomas Jefferson      /example-image-10x16.jpg/ 7  /13,
    James Madison         /example-image-10x16.jpg/12.5/20,
    James Monroe          /example-image-10x16.jpg/17  /20,
    John Quincy Adams     /example-image-10x16.jpg/21.5/20,
    Andrew Jackson        /example-image-10x16.jpg/26  /20,
    Martin Van Buren      /example-image-10x16.jpg/30.5/20,
    William Henry Harrison/example-image-10x16.jpg/36  /13,
    John Tyler            /example-image-10x16.jpg/37.5/10,
    James K Polk          /example-image-10x16.jpg/39  / 7}

\begin{document}
\noindent
\begin{tikzpicture}
  \useasboundingbox (0,0) rectangle (17in,11in);% see http://tex.stackexchange.com/a/98532/16595

  \draw[line width=5mm] (5,5) -- (10,15);
  \draw[line width=5mm] (12,18) -- (31,18);
  \draw[line width=5mm] (38,5) -- (33,15);

  \foreach \sName/\sFile/\sX/\sY in \ListOfStudents {\student{\sX}{\sY}{\sName}{\sFile}}
\end{tikzpicture}
\end{document}

Output

enter image description here

More Advanced

If you want to have separate lists we can find the right pairs by using nested \foreach loops and two counters we can compare (if they are equal we have the right pair of (file) name and coordinates).

If no file name is given it is constructed via the lowercase name and spaces substituted with dashes (-). The xstring package is used for the substituting part.

I have also added the option that if a file name is given the extension .jpg is added automatically (although TeX/graphicx has its own rules how to deal with file names without an extension).

Note that the following code throws errors and warnings as the files are not available (but we have an easy way to check the outcoming file name).

Code

\documentclass[10pt]{article}
\usepackage[margin=0in,paperwidth=17in, paperheight=11in]{geometry}
\usepackage{xstring}
\usepackage{tikz}

% Usage: \student{x coord}{y coord}{name}{picture file}
\newcommand{\student}[4]{%
  \node[anchor=base,inner sep=0,
      label={[text width=20mm,align=center]below:#3}] at (#1,#2)
      {\includegraphics[width=17mm]{#4}};%
}

\newcommand{\ListOfSeats}{%
  4/7, 5.5/10, 7/13, 12.5/20, 17/20, 21.5/20, 26/20, 30.5/20, 36/13, 37.5/10, 39/7}

\newcommand*{\ListOfStudents}{%
    George Washington,
    John Adams,
    Thomas Jefferson,
    James Madison,
    James Monroe/different-filename,
    John Quincy Adams,
    Andrew Jackson,
    Martin Van Buren,
    William Henry Harrison/wh-harrison,
    John Tyler,
    James K Polk}

\begin{document}
\noindent
\begin{tikzpicture}
  \useasboundingbox (0,0) rectangle (17in,11in);% see http://tex.stackexchange.com/a/98532/16595

  \draw[line width=5mm] (5,5) -- (10,15);
  \draw[line width=5mm] (12,18) -- (31,18);
  \draw[line width=5mm] (38,5) -- (33,15);
  \foreach \sName/\sFile[count=\iOuter from 0] in \ListOfStudents {
    \foreach \sX/\sY[count=\iInner from 0] in \ListOfSeats {
      \ifnum\iOuter=\iInner
        \ifx\sName\sFile
          \expandafter\lowercase\expandafter{\expandafter\def\expandafter\sFile\expandafter{\sName.jpg}}
          \StrSubstitute{\sFile}{ }{-}[\sFile]
        \else \edef\sFile{\sFile.jpg}% includes automatically the extension .jpg (comment line out if not needed)
        \fi
        \student{\sX}{\sY}{\sName}{\sFile}
        \breakforeach
      \fi
    }
  }
\end{tikzpicture}
\end{document}

Output

enter image description here

share|improve this answer
    
The file-name-constructing code can also be implemented in the first solution … –  Qrrbrbirlbel Feb 17 '13 at 8:22
    
Thank you for your help! This is a great solution and I learned quite a few LaTeX commands that I did not know about before. –  I Like to Code Feb 17 '13 at 14:07
    
@ILiketoCode The macros \ifx, \ifnum, \else and \fi are technically TeX macros (as are \expandafter, \def and \lowercase), I have used them for simplicity. If you rather want a LaTeX approach (better input, better conditionals), the packages xstring and xifthen both offer a few macros that makes it easier to build conditionals (for example string testing). –  Qrrbrbirlbel Feb 17 '13 at 15:45
add comment

At the risk of irritating Werner [:)], I would say that, with \newforeach, all elements (including file names, e.g., example-image-10x16.jpg) can be surrounded by spaces.

\documentclass[10pt]{article}
\usepackage[margin=0in,paperwidth=17in, paperheight=11in]{geometry}
\usepackage{tikz,loops}
\newcommand*{\ListOfStudents}{%
    George Washington      / example-image-10x16.jpg / 4      / 7,
    John Adams             / example-image-10x16.jpg / 5.5    / 10,
    Thomas Jefferson       / example-image-10x16.jpg / 7      / 13,
    James Madison          / example-image-10x16.jpg / 12.5   / 20,
    James Monroe           / example-image-10x16.jpg / 17     / 20,
    John Quincy Adams      / example-image-10x16.jpg / 21.5   / 20,
    Andrew Jackson         / example-image-10x16.jpg / 26     / 20,
    Martin Van Buren       / example-image-10x16.jpg / 30.5   / 20,
    William Henry Harrison / example-image-10x16.jpg / 36     / 13,
    John Tyler             / example-image-10x16.jpg / 37.5   / 10,
    James K Polk           / example-image-10x16.jpg / 39     / 7
}

\begin{document}
\noindent
\begin{tikzpicture}
\useasboundingbox (0,0) rectangle (17in,11in);
\draw[line width=5mm] (5,5) -- (10,15);
\draw[line width=5mm] (12,18) -- (31,18);
\draw[line width=5mm] (38,5) -- (33,15);
\newforeach [expand list once=true] \name/\file/\x/\y in \ListOfStudents{%
  \node[anchor=base,inner sep=0,
    label={[text width=20mm,align=center]below:\name}] at (\x,\y)
      {\includegraphics[width=17mm]{\file}};
}
\end{tikzpicture}
\end{document} 

enter image description here

We could also have used

\foreachfox [expand list once=true, arg=#1/#2/#3/#4]\ListOfStudents{%
  \edef\tempa{\skvtrimspace{#2}}%
  \node[anchor=base,inner sep=0,
    label={[text width=20mm,align=center]below:#1}] at (#3,#4)
      {\includegraphics[width=17mm]{\tempa}};
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.