9

I have a simple diagram I have created.

\begin{figure}[t]
  \begin{center}
    \setlength{\unitlength}{10pt}
    \begin{picture}(24,4)
      \setlength\fboxsep{0pt}
      \put(0,2){$\underbrace{\strut \fcolorbox{black}{teal0}{\framebox(6,2){Preamble}}\fcolorbox{black}{purp0}{\framebox(7,2){Start code}}}_\textrm{Stage 1: estimate M}$}
      \put(13,2){$\underbrace{\strut \fcolorbox{black}{lime0}{\framebox(5,2){Data}}\fcolorbox{black}{orange0}{\framebox(6,2){Stop code}}}_\textrm{Stage 2: sample and decode}$}
    \end{picture}
    \caption{Packet format.}
    \label{fig:packet}
  \end{center}
\end{figure}

and it creates the following: enter image description here

However, if you look closely you will notice the text in the last box is out of alignment with the text in the other boxes because of the "p". I would like to put it in alignment. Solution should be as close to the original image as possible, and not require additional packages like TikZ.

  • using the amsmath package, one can simply "smash" the bottom of a word with descenders: \smash[b]{Stop} code – barbara beeton Jun 3 '13 at 12:37
7

Please always post complete documents showing all packages (and colours) used. I made up some different colours.

As you are in picture mode anyway it is easier to directly control the position of the braces using \put coordinates, and you can hide the depth of the text using \raisebox. enter image description here

\documentclass{article}
\usepackage{color}
\begin{document}

\begin{figure}[t]
  \begin{center}
    \setlength{\unitlength}{10pt}
    \begin{picture}(24,4)
      \setlength\fboxsep{0pt}
      \put(0,2){\fcolorbox{black}{red}{\framebox(6,2){Preamble}}%
                \fcolorbox{black}{blue}{\framebox(7,2){Start code}}%
                \fcolorbox{black}{yellow}{\framebox(5,2){Data}}%
                \fcolorbox{black}{green}{\framebox(6,2){\raisebox{0pt}[\height][0pt]{Stop code}}}}

      \put(0,0){\makebox(13.2,2){\upbracefill}\makebox(11.2,2){\upbracefill}}

      \put(0,-1){\makebox(13.2,2){Stage 1: estimate M}%
                \makebox(11.2,2){Stage 2: sample and decode}}



    \end{picture}
    \caption{Packet format.}
    \label{fig:packet}
  \end{center}
\end{figure}

\end{document}
  • 1
    Concise answer, clean code, and you improved the braces for bonus points. Thanks. – travisbartley Jun 3 '13 at 9:04
  • I didn't notice it before, but this answer does not include the text under the braces as in the original. – travisbartley Jun 5 '13 at 7:21
  • @trav1s well I spotted that after I'd posted but since it's easy to put them back I didn't think it worth re-creating the image:-) – David Carlisle Jun 5 '13 at 8:23
  • 1
    @trav1s I added the label back to the code:-) – David Carlisle Jun 5 '13 at 8:29
10

It's all about the placement of the \strut:

enter image description here

\documentclass{article}
\usepackage{xcolor}% http://ctan.org/pkg/xcolor

\begin{document}

\begin{center}
  \setlength{\unitlength}{10pt}
  \begin{picture}(24,4)
    \setlength\fboxsep{0pt}
    \put(0,2){$\underbrace{\strut \fcolorbox{black}{red}{\framebox(6,2){Preamble}}\fcolorbox{black}{blue}{\framebox(7,2){Start code}}}_\textrm{Stage 1: estimate M}$}%
    \put(13,2){$\underbrace{\strut \fcolorbox{black}{green}{\framebox(5,2){Data}}\fcolorbox{black}{yellow}{\framebox(6,2){Stop code}}}_\textrm{Stage 2: sample and decode}$}
  \end{picture}
\end{center}

\begin{center}
  \setlength{\unitlength}{10pt}
  \begin{picture}(24,4)
    \setlength\fboxsep{0pt}
    \put(0,2){$\underbrace{\fcolorbox{black}{red}{\framebox(6,2){\strut Preamble}}\fcolorbox{black}{blue}{\framebox(7,2){\strut Start code}}}_\textrm{Stage 1: estimate M}$}%
    \put(13,2){$\underbrace{\fcolorbox{black}{green}{\framebox(5,2){\strut Data}}\fcolorbox{black}{yellow}{\framebox(6,2){\strut Stop code}}}_\textrm{Stage 2: sample and decode}$}
  \end{picture}
\end{center}

\end{document}

The upper image is the original output, while the lower one uses a \strut in each box. Since you are using \fcolorbox, you can create something like

\newcommand{\paddedbox}[4][1ex]{%
  {\setlength{\fboxsep}{#1}\fcolorbox{#2}{#3}{\strut\quad#4\quad}}}%

which creates a padded box (through setting \fboxsep; default is 1ex), vertically and horizontally (through additional placements of \quads (1em space). The code is a little cleaner

\begin{center}
  \setlength{\unitlength}{10pt}
  \begin{picture}(24,4)
    \put(0,2){$\underbrace{\paddedbox{black}{red}{Preamble}\paddedbox{black}{blue}{Start code}}_\textrm{Stage 1: estimate M}$}%
    \put(15,2){$\underbrace{\paddedbox{black}{green}{Data}\paddedbox{black}{yellow}{Stop code}}_\textrm{Stage 2: sample and decode}$}
  \end{picture}
\end{center}

and produces

enter image description here

  • I should clarify, the original /struts were used to produce spacing between the boxes and the brackets. Your answer is correct that adding a /strut to each box does put them all in alignment with eachother. But now they are slightly higher than center. What I would like is to move the "Stop code" text in the original text down, instead of moving the others up. Sorry if this is getting a little anal retentive! – travisbartley Jun 3 '13 at 5:43
  • 1
    @trav1s: Use \vphantom{S}\smash{Stop code} The you get the appropriate height of the letter S (a capital letter without a descender) but without setting it, followed by a zero height-depth setting of Stop code since it's \smashed. – Werner Jun 3 '13 at 5:58
  • @trav1s You could adapt Werner's answer to use your custom struts, e.g. \newcommand*{\mystrut}{\rule[-0.2\baselineskip]{0pt}{0.7\baselineskip}}, and control the height of your boxes that way. I once wrote a detailed answer with more details if you're interested. – Xavier Jun 3 '13 at 6:01
5

For reference, the same problem with TikZ could be fixed as shown in Problem with TikZ and vertical alignment of text inside nodes.

Combining that hint with Connecting nodes with brace in TikZ, it is possible to build the following solution:

\documentclass{article}
\usepackage{tikz,pdftexcmds}
\usetikzlibrary{calc,shapes.arrows,decorations.pathreplacing,shadows}

% list of keys
\pgfkeys{/tikz/.cd,
  border color/.initial=black,
  border color/.get=\bordercol,
  border color/.store in=\bordercol,
  brace color/.initial=black,
  brace color/.get=\bracecol,
  brace color/.store in=\bracecol,
  brace distance/.initial=5pt,
  brace distance/.get=\bracedistance,
  brace distance/.store in=\bracedistance,
  brace position/.initial=north,
  brace position/.get=\bracepos,
  brace position/.store in=\bracepos,
  items height/.initial=1cm,
  items height/.get=\itemheight,
  items height/.store in=\itemheight,
  items width/.initial=3cm,
  items width/.get=\itemwidth,
  items width/.store in=\itemwidth,
  items distance/.initial=\itemwidth,
  items distance/.get=\itemdistance,
  items distance/.store in=\itemdistance,  
}

% list of styles
\tikzset{module/.style={
    draw=\bordercol,
    minimum height=\itemheight,
    minimum width=\itemwidth,
    text height=1.5ex,
    text depth=.25ex,
  },
  brace/.style={
    decoration={brace,raise=\bracedistance,amplitude=0.75em,#1},
    decorate,
    draw=\bracecol,
    very thick,    
  }
}

\makeatletter
\newcommand{\braceddiagram}[3][]{
  \begin{tikzpicture}[scale=0.9,transform shape,#1] % here we can pass options:
      % scale=0.9,transform shape are used to avoid overfull and underfull boxes

     % counting all the items to be displayed
     \foreach \items/\colors [count=\xi] in {#2}{\global\let\maxnumitem\xi}

     % foreach item we are going to compute at which distance it should be located
     % and then we put it with the module style and with a name <module><num-module>
     \foreach \items/\colors [count=\xi] in {#2}{%
       \path let 
         \n1={0+\xi*\itemdistance} in
         node[module,fill=\colors] (module\xi) at +(\n1,0) {\items};
     }

     % at the end we draw the brace with the comment
     \ifnum\pdf@strcmp{\bracepos}{south}=\z@
       \draw[brace=mirror] (module1.south west)--(module\maxnumitem.south east)
        node[below=3*\bracedistance, midway]{#3};
     \else
       \draw[brace] (module1.north west)--(module\maxnumitem.north east)
        node[above=3*\bracedistance, midway]{#3};
     \fi

  \end{tikzpicture}
}
\makeatother


\begin{document}

Generic examples:

\braceddiagram[brace distance=4pt]{Bla/red, Bla/blue, Bla/green}{Some comment}

\vspace{1cm}

\tikzset{my style for the diagram/.style={
    brace distance=6pt,
    brace position=south,
  }
}

\braceddiagram[my style for the diagram]{Bla/red, Bla/blue, Bla/green,Bla/yellow}{Some other comment}

\vspace{1cm}

The real example:

\begin{center}
\braceddiagram[my style for the diagram]{Preamble/red, Start code/blue}{Stage 1: estimate M}
\braceddiagram[my style for the diagram]{Data/green,Stop code/yellow}{Stage 2: sample and decode}
\end{center}

\end{document}

The result:

enter image description here

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.