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.

I draw the following horizontal line with node and want to draw underbrace/overbrace between some nodes. Please let me know how to do that.

%draw horizontal line   
\draw (0,0) -- (8,0);

%draw vertical lines
\foreach \x in {0,2.3,4,8}
   \draw (\x cm,3pt) -- (\x cm,-3pt);

%draw nodes
\draw (0,0) node[below=3pt] {$ \underline{c} $} node[above=3pt] {$   $};
\draw (2.3,0) node[below=3pt] {$ c_A^{*} $} node[above=3pt] {$ $};
\draw (4,0) node[below=3pt] {$ c_B^{*} $} node[above=3pt] {$ $};
\draw (8,0) node[below=3pt] {$\overline{c} $} node[above=3pt] {$ $};
share|improve this question
    
Hi Justin, welcome to TeX.sx! I've formatted your code, which you can also do yourself by selecting it and clicking the {} button. I have also removed the "Thanks" from your question, which is just the style used on this site. –  Jake Nov 11 '11 at 6:11
add comment

1 Answer

I would use the decorations.pathreplacing TikZ library for this, which lets you replace a path, which provides a brace decoration.

The first thing you have to do to get a brace is to draw a line which will later become your path. Since you use nodes in your drawing (not just coordinates), it makes sense to use these for positioning the brace. In order to use the nodes for positioning new elements, they need to be named. This can be done by using the syntax \node (<name>) at (<coordinates>) [<options>] {<text>}; or by using the name option in the <options>.

I would also define a new style for the label nodes, which will make it easier later on if you want to change the offset, the color, size or any other property of all the nodes simultaneously. I would draw the nodes like this:

\tikzset{
    position label/.style={
       below = 3pt
    }
}

\node [position label] (cStart) at (0,0) {$ \underline{c} $};
\node [position label] (cA) at (2.3,0) {$ c_A^{*} $};
\node [position label] (cB) at (4,0) {$ c_B^{*} $};
\node [position label] (cEnd) at (8,0) {$\overline{c} $};

Then you can draw the line that will become the brace. To connect the first two nodes, you might say

\draw (cStart.south) -- (cA.south);

However, this doesn't quite work

The line isn't horizontal, because the south anchors of the two nodes are at different y-coordinates.

There are many different ways of getting the lines to be horizontal:

  • You could use the -| syntax: \draw (cStart.south) -- (cStart.south -| cA.south), which will draw a line from (cStart.south) to the intersection of a horizontal line passing through (cStart.south) and a vertical line passing through (cA.south)

  • You could use the let syntax: \draw let \p1=(cStart.south), \p2=(cA.south) in (\p1) -- (\x2,\y1);, which saves the two coordinates into macros \p1 and \p2 and lets you access the x and y components of each point separately

  • You could define all nodes to have the same text depth and text height, which will place the south and north anchor at the same distance from the node center, regardless of the node text. I would go with this, since it makes for the most readable code for the lines and also aligns all the $c$ nicely, plus it makes sure that all braces will end up at the same vertical position, regardless of which nodes they're connecting.

Here's the new code for the nodes and the line:

\tikzset{
    position label/.style={
       below = 3pt,
       text height = 2ex,
       text depth = 1ex
    }
}

\node [position label] (cStart) at (0,0) {$ \underline{c} $};
\node [position label] (cA) at (2.3,0) {$ c_A^{*} $};
\node [position label] (cB) at (4,0) {$ c_B^{*} $};
\node [position label] (cEnd) at (8,0) {$\overline{c} $};

Now the line can be converted into a brace. To do that, you first define a decoration, using the key decoration={brace}, and then apply that decoration using the key decorate:

\draw [decoration={brace}, decorate] (cStart.south) -- (cA.south);

Almost there: The brace is pointing in the wrong direction. You can now either reverse the direction you draw your path in by saying \draw [decoration={brace}, decorate] (cA.south) -- (cStart.south);, or swap the direction of the decoration, by saying `decoration={brace, mirror}. I'd go with the second option. This can also be wrapped into a style, et voila:

\tikzset{
    position label/.style={
       below = 3pt,
       text height = 1.5ex,
       text depth = 1ex
    },
   brace/.style={
     decoration={brace, mirror},
     decorate
   }
}

\node [position label] (cStart) at (0,0) {$ \underline{c} $};
\node [position label] (cA) at (2.3,0) {$ c_A^{*} $};
\node [position label] (cB) at (4,0) {$ c_B^{*} $};
\node [position label] (cEnd) at (8,0) {$\overline{c} $};

\draw [brace] (cStart.south) -- (cA.south);

Bonus: If you want to label the brace, you can place a node while you're constructing the path:

     \draw [brace] (cStart.south) -- (cA.south) node [position label, pos=0.5] {First};

or

\draw [brace] (cStart.south) -- node [position label, pos=0.5] {First} (cA.south);

will both place a node halfway along the path (notice the different position of the node keyword: In the first case, it's after the second coordinate of the path, which means you have to use pos=0.5 to specify the halfway point. In the second case, node comes before the second coordinate, which will automatically place the node halfway along the line).

To add a second brace that doesn't overlap with the first, you can use the raise option for the decoration. This will not influence the placement of the label node (because that's relative to the undecorated path), so you will have to supply a yshift of the same length to the node definition:

\draw [brace,decoration={raise=4ex}] (cStart.south) -- node [position label,yshift=-4ex] {Second} (cB.south);

share|improve this answer
    
Thanks Jake. That's really helpful for me. –  justin Nov 11 '11 at 6:55
    
Thanks again. Now, I want to draw another underbrace between cStart and cB without overlapping. How could I do that? –  justin Nov 11 '11 at 7:34
    
Thanks Jake. That's really helpful to me. –  justin Nov 12 '11 at 18:59
    
@justin: Glad it helps! If you consider your question answered, you can mark it as such by clicking the green tick mark next to the answer (and you can also upvote it by clicking the upward pointing arrow next to the answer). –  Jake Nov 13 '11 at 3:53
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.