10

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.

1
  • using the amsmath package, one can simply "smash" the bottom of a word with descenders: \smash[b]{Stop} code Commented Jun 3, 2013 at 12:37

3 Answers 3

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}
4
  • 1
    Concise answer, clean code, and you improved the braces for bonus points. Thanks. Commented Jun 3, 2013 at 9:04
  • I didn't notice it before, but this answer does not include the text under the braces as in the original. Commented Jun 5, 2013 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:-) Commented Jun 5, 2013 at 8:23
  • 1
    @trav1s I added the label back to the code:-) Commented Jun 5, 2013 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

3
  • 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! Commented Jun 3, 2013 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
    Commented Jun 3, 2013 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
    Commented Jun 3, 2013 at 6:01
6

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .