1

I'm trying to typeset a diagram with two boxes and an arrow between them. I'd like the boxes to be labeled by some text (math text, e.g. \mathsf{C}) but the only way I found to do that is unsatisfying (using \underset, the text is too small and the placement suboptimal).

This is the situation I have now:

before

This is what I want to achieve (possibly with better-than-my-paint-skills alignment):

after

This is the working code:

\[
    \underset{\cat{J}}{
        \fbox{
            \begin{tikzcd}
                \& \& \bullet \arrow{dl}\\
                \bullet \arrow[shift left]{r} \arrow[shift right]{r} \& \bullet \arrow{dr}\\
                \& \& \bullet
            \end{tikzcd}
        }
    }
    \begin{tikzcd}
        \phantom{.} \arrow[mapsto]{r}{F} \& \phantom{.}
    \end{tikzcd}
    \underset{\cat{C}}{
        \fbox{
            \begin{tikzcd}
                \& \& X \arrow{dl}{f}\\
                A \arrow[shift left]{r}{j} \arrow[shift right, swap]{r}{k} \& B \arrow{dr}{g}\\
                \& \& Y
            \end{tikzcd}
        }
    }
\]
  • You can use saveboxes to measure the size of the tikzcd images and use things like \llap, \rlap and \raisebox to add the labels. You can even use the saveboxes inside another tikzpicture. I would show you how if you had a MWE instead of just a code fragment. – John Kormylo May 5 '18 at 13:21
5

You could draw the box and add the label with TikZ, via execute at end picture. Define a style like this

\tikzset{
  frame and label/.style={
    execute at end picture={
      % if you want some extra padding, like \fbox does, you can use shift like this
      \draw ([shift={(2pt,-2pt)}]current bounding box.south east) rectangle
            ([shift={(-2pt,2pt)}]current bounding box.north west) 
            % the overlay option means that the node is not taken into account when the bounding box is set
            node[below left, overlay] {$\mathsf{#1}$};
    }   
  }
}

And use it like this:

\begin{tikzcd}[frame and label=J]

Some notes: As mentioned in the comment in the code, the overlayoption means that the node is included in the bounding box if the tikzpicture. This means for example that the label will not affect the space between the arrow in the middle and the frame of the right diagram.

An \fbox adds a little bit of padding (and you also have some extra horizontal space due to not ending some lines with %), the [shift=..] in the coordinates do a similar job. Remove, or adjust 2pt as you see fit, of course.

enter image description here

\documentclass{article}    
\usepackage{tikz-cd,amsmath}
\tikzcdset{ampersand replacement=\&}
\tikzset{
  frame and label/.style={
    execute at end picture={
      % if you want some extra padding, like \fbox does, you can use shift like this
      \draw ([shift={(2pt,-2pt)}]current bounding box.south east) rectangle
            ([shift={(-2pt,2pt)}]current bounding box.north west) 
            % the overlay option means that the node is not taken into account when the bounding box is set
            node[below left, overlay] {$\mathsf{#1}$};
    }   
  }
}
\begin{document}
\[
  \begin{tikzcd}[frame and label=J]
      \& \& \bullet \arrow{dl}\\
      \bullet \arrow[shift left]{r} \arrow[shift right]{r} \& \bullet \arrow{dr}\\
      \& \& \bullet
  \end{tikzcd}
  \begin{tikzcd}
      \phantom{.} \arrow[mapsto]{r}{F} \& \phantom{.}
  \end{tikzcd}
  \begin{tikzcd}[frame and label=C]
      \& \& X \arrow{dl}{f}\\
      A \arrow[shift left]{r}{j} \arrow[shift right, swap]{r}{k} \& B \arrow{dr}{g}\\
      \& \& Y
  \end{tikzcd}
\]
\end{document}

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.