8

How to align text under the brackets:

enter image description here

\documentclass{article}
\usepackage{amsmath}
\begin{document}
\[
\underbrace{(zzz)}_{\textrm{tall}}
\underbrace{zzz}_{\textrm{short}}
\]
\end{document}
8
  • I've taken the liberty of adding a few instructions to your code snippet to make it minimally compilable.
    – Mico
    Mar 23 at 14:10
  • 2
    Since the "deepest" characters in the first and last elements of the expression are the parentheses, I'd simply add \vphantom{)} to the middle element. (This has probably been addressed before, but I didn't look.) Mar 23 at 14:19
  • @barbarabeeton: Yes misalignment is due to descenders in characters. When I try this: \underbrace{Y(z)}_{\textrm{output}} \underbrace{\vphantom{z^{-1}}}_{\textrm{delay}}, it's still misaligned. What's wrong? I'm following this answer.
    – mins
    Mar 23 at 15:26
  • The \vphantom needs to contain something with the required depth, and z^{-1} doesn't have any depth. At first, you'll need to analyze the situation character by character; with time, it becomes automatic. Mar 23 at 16:40
  • Since the example in your question has been changed, I'll try to explain "depth" with reference to the new example. Locate the baseline -- it is the level on which the z, like all letters with no descenders, sits. The \underbrace is placed a fixed distance below the baseline in that case. But when parentheses are added, they do have depth, and the underbrace is placed a fixed distance (the same amount as in the first case) below the lowest point of the parentheses. When a \vphantom is added, that resets the lowest (and highest) point of the expression, moving the underbrace down. Mar 23 at 19:12

3 Answers 3

10

You want to make the formulas to have the same height. Here I use \mathstrut, but in the optional argument you may use any \vphantom.

\documentclass{article}
\usepackage{amsmath}

\newcommand{\ubracetext}[3][\mathstrut]{%
  \mathinner{%
    \underbrace{#1#2}_{\textrm{\vphantom{X}#3}}%
  }%
}

\begin{document}

\begin{equation*}
\ubracetext{Y(z)}{output} =
\ubracetext{z^{-1}}{delay}
\ubracetext{X(z)}{input}
\end{equation*}

\end{document}

enter image description here

In case of need you can do

\ubracetext[\vphantom{<formula>}]{top}{bottom}

Note that spaces in the final argument (the subscript) are honored; don't add them just to keep alignment in the source code.

6
  • Can it be done without a custom command?
    – mins
    Mar 23 at 14:17
  • \mathstrut is not a custom command.
    – Mico
    Mar 23 at 14:18
  • @mins Yes, of course, but why?
    – egreg
    Mar 23 at 14:18
  • I use Lyx and don't know about defining macros. @Mico, I mean \newcommand{\ubracetext}.
    – mins
    Mar 23 at 14:20
  • 3
    @mins You should learn (or avoid LyX). Do you like to type in \underbrace{\mathstrut Y(z)}_{\textrm{\vphantom{X}input}}? I don't.
    – egreg
    Mar 23 at 14:32
10

The reason the middle of the three underbraces isn't aligned vertically with the other two is that the first argument of the associated \underbrace directive doesn't contain material that protrudes below the baseline; in contrast, the first arguments of the first and third \underbrace directive contain ( and ).

To fix this issue, I suggest you insert the instruction \mathstrut -- which is defined as \vphantom{)} -- next to z^{-1}. I would also use \textnormal (or \textup) instead of \textrm. And I'd use a \mathclap directive to let the word "output" to the left and right of the associated brace.

And, for the utmost in typesetting class, insert \vphantom{d} directives (\vphantom{l} will do too) in the second arguments of the first and third \underbrace directives.

If your document contains a lot of these expressions, I'd consider creating a custom macro -- along the lines given in @egreg's answer -- to simplify and standardize creating these underbrace expressions.

enter image description here

\documentclass{article}
\usepackage{mathtools} % for \mathclap macro
\begin{document}
\[
\underbrace{Y(z)} _{\mathclap{\textnormal{output\vphantom{d}}}} =
\underbrace{z^{-1}\mathstrut} _{\textnormal{delay}}\,
\underbrace{X(z)} _{\textnormal{input}\vphantom{d}}
\]
\end{document}

Addendum -- I just noticed that the OP has changed and simplified their query. As a result, the specifics of the answer given above may no longer be all that useful. However, the principles that underlie the suggested adjustmens remain the same. Take the OP's new code block:

\[
\underbrace{(zzz)}_{\textrm{tall}}
\underbrace{zzz}_{\textrm{short}}
\]

Observe that the first argument of the first \underbrace directive contains (, which protrudes below the baseline, whereas the first argument of the second \underbrace directive does not. To fix the resulting difference in the depths at which the horizontal braces are placed, insert a \mathstrut directive in the second line:

\[
\underbrace{(zzz)}_{\textrm{tall}}
\underbrace{zzz\mathstrut}_{\textrm{short}}
\]

This works perfectly because \mathstrut is defined as as \vphantom{(}, which is a typographic strut with some height and (importantly) depth -- and no width, which makes it invisible, justifying the "phantom" part in \vphantom.

enter image description here

\documentclass{article}
\usepackage{amsmath} % for '\underbrace' and '\text' macros
\begin{document}
\[
\underbrace{(zzz)}_{\textrm{tall}}  \underbrace{zzz}_{\textrm{short}}
\quad\text{vs.}\quad
\underbrace{(zzz)}_{\textrm{tall}}\,\underbrace{zzz\mathstrut}_{\textrm{short}}
\]
\end{document}
1

Short answer

Add the same \vphantom spacer to all underbraces, passing it the character with the longest descender. The \vphantom itself can be anywhere in the argument of the \underbrace command:

\underbrace{(zzz)\vphantom{(}}_{\textrm{tall}}
\underbrace{zzz  \vphantom{(}}_{\textrm{short}}

![enter image description here

Lyx procedure

In Lyx, such spacers can be added using menu Insert | Formatting | Phantom (more), or by using the Math Spacing menu from the toolbar:

enter image description here

Type the text to use as argument, select it and insert the spacer. Spacers appear as red arrows over their grayed argument, which can be edited at any time, the result is updated interactively:

![enter image description here


Details

After some trials I was able to understand how this works, here is a solution not using macros/definitions, because:

  • I've only a few occurrences of misalignment.

  • I prefer self-contained commands, to keep the code portable from one document to another without the constraint of adjusting header/preamble.

Cause of the misalignment

Underbrace anchors itself to a vertical position which is based on the longest character descender. Descenders are these bottom parts of some glyphs extending below the typesetting baseline, e.g. in y or g.

Hence this anchoring position varies from one underbrace to the other, as their argument is not guaranteed to contain the same descenders. Unfortunately in Latex there is no built-in mechanism for underbraces on the same line to automatically negotiate their vertical position.

Solution

The bypass is to add the character with the tallest glyph to all underbraces, so they compute the same vertical position.

However we don't want this additional character to appear. Fortunately there is a helper, \phantom, creating a transparent area encompassing whatever is provided for its argument and thus taking into account possible descenders.

The name "phantom" makes sense, since the argument passed to the helper is not displayed and only used to force a spacing.

Of course we are only interested in the vertical space created, we don't want to add an empty horizontal space. There are two variants to \phantom, one which exposes only a width (\hphantom), one exposing only a height (\vphantom). Thus we can use \vphantom.

(For the sake of completeness, there is another solution using rule, but said to be "fragile".)

Choice of vphantom argument

The argument of \vphantom can be anything, usually one character. We choose the character with the longest descender in all underbraces.

Alphabetic characters with long descenders: jpqy({[|]}).

Note actual bounding box depends on the glyph, thus on the font used. In particular numbers in fonts with oldstyle glyphs for numerals have long descenders, and some glyphs like for s can have a decorative swash. So using ( or ) is not guaranteed to succeed in specific cases. A word-processing application with decent wysiwyg is helpful.

In math formulas, there are chances some symbol will be the choice (symbols such as integral may be chosen, including their limits).

Nothing prevents to pass multiple characters and let the feature compute the outmost bounding box by itself.

Final code

Replace this code:

\underbrace{(zzz)_{\textrm{tall}}
\underbrace{zzz }_{\textrm{short}}

by:

\underbrace{(zzz)\vphantom{(}}_{\textrm{tall}}
\underbrace{zzz\vphantom{(}}  _{\textrm{short}}

Thanks to Barbara, Mico and egreg for suggesting good elements to build this answer. Look at their answers as well, they contain alternatives which may suit your needs.

2
  • 2
    Please see the addendum I posted below my answer. Your proposed adjustment "works" because the glyphs ( and | happen to have the same depth if Computer Modern Math is the math alphabet in use; this need not be the case for other math fonts. To "play it safe", I'd suggest using \vphantom{(} instead of \vphantom{|} in the first argument of \underbrace.
    – Mico
    Mar 24 at 11:44
  • @Mico: You're right, this choice is better. Answer edited.
    – mins
    Mar 24 at 12:02

You must log in to answer this question.

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