3

I have two problems. They seem related enough to be included in the same question. These are most easily described with the following example.

enter image description here I would prefer if all the vertical arrows were aligned, like in the following example: enter image description here

How do you center a tikz-cd diagram to what looks more like the true center of the diagram? I tried adding phantom points beyond the labels, so that the diagram would center using the phatom points, but this seems ad-hoc.

What is the best practice for adjust the length of arrows to give a uniform look? I understand that the arrow lengths can be adjusted manually using [sep=3em]. But it seems there should be better way.

Here is the minimal working example used to make the first image. The second image was edited in Gimp.

\usepackage{tikz-cd}
\begin{document}
\noindent{Here is the first diagram.} 
\[\begin{tikzcd}
A & B \\
C & D
\arrow[from=1-1, to=1-2]
\arrow[from=1-2, to=2-2]
\arrow[from=1-1, to=2-1]
\arrow[from=2-1, to=2-2]
\end{tikzcd}\]
Here is the second diagram. The long label throws off the centering.
\[\begin{tikzcd}
A & B \\
C & D
\arrow[from=1-1, to=1-2]
\arrow["{\text{long label}}", from=1-2, to=2-2]
\arrow[from=1-1, to=2-1]
\arrow[from=2-1, to=2-2]
\end{tikzcd}\]
Here is the third diagram. It looks too wide.
\[\begin{tikzcd}
{A+E} & {B+E} \\
{C+E} & {D+E}
\arrow[from=1-1, to=1-2]
\arrow[from=1-2, to=2-2]
\arrow[from=1-1, to=2-1]
\arrow[from=2-1, to=2-2]
\end{tikzcd}\]
\end{document}
6
  • 3
    What about "\rlap{\scriptsize long label}"?
    – Sigur
    Commented Sep 29, 2022 at 0:07
  • Nice! that works perfect!
    – samlanader
    Commented Sep 29, 2022 at 0:55
  • @Sigur, I am having trouble getting this to work when the lable is on the other side "\rlap{label}" ' What is the way to use this for a label on the left
    – samlanader
    Commented Sep 29, 2022 at 1:02
  • 1
    In this case, you have to insert the label on the other side of the arrow using "\llap{\scriptsize long label}"'. Pay attention on the extra single quote to insert the label on the other side of the arrow.
    – Sigur
    Commented Sep 29, 2022 at 1:07
  • 1
    Unrelated: \noindent does not take an argument. The curly braces around the stuff that follows are not necessary. Commented Oct 31, 2022 at 8:21

2 Answers 2

2

The label long label contributes to the bounding box of the TikZ picture (usually something you want), however, with the option overlay you can instruct TikZ to ignore the label for the bounding box altogether.
Since you've used \text (from amsmath?)I've also added a no math key that a) switches off math-mode for the labels of that edge and b) sets the fontsize of the label to \scriptsize (where \scriptstyle is used for math-mode). The no math key needs to be used as an option to the arrow and not the label itself.

You can also use the options trim left and trim right (as I did in another answer) so that only the matrix itself will determine the horizontal size of the diagram. This is a more general solution but may have disadvantage with wider and complex diagrams?


The underlying TikZ matrix that is used by TikZ-CD also supports the columns to be spaced by a distance between their origins (and not their borders), this means you need to specify between origins when giving a column seperation. Unfortunately, the default value and the values predefined by TikZ-CD aren't easily accessible then but you need to specify the length more or less on your own anyway because this is of course dependent on all your diagrams and the content of the cells. I'm randomly choosing 4.6em since it looks good for that case but you can of course change the default value or use columns from center=<distance> manually.

Should this be done more automatically, the width of the nodes need to be measured or the widest node needs to be specified by the user and taken into account, this is possible but there are many cases that need to be considered (how should a diagram with three columns look?).

Code

\documentclass[varwidth,border=2mm]{standalone}
\usepackage{tikz-cd}
\tikzcdset{
  center matrix/.style={
    trim left=(\tikzcdmatrixname.west),
    trim right=(\tikzcdmatrixname.east)},
  columns from center/.default=4.6em,
  columns from center/.style={column sep={#1,between origins}},
  no math/.style={
    every label/.append style={font=\scriptsize},
    math mode=false}}
\begin{document}
Here is the first diagram.
\[\begin{tikzcd}[columns from center]
  A & B \\
  C & D
  \arrow[from=1-1, to=1-2]
  \arrow[from=1-2, to=2-2]
  \arrow[from=1-1, to=2-1]
  \arrow[from=2-1, to=2-2]
\end{tikzcd}\]
Here is the second diagram. The long label throws off the centering.

\textcolor{red}{→ Use \texttt{overlay} (and \texttt{no math}).}
\[\begin{tikzcd}[columns from center]
  A & B \\
  C & D
  \arrow[from=1-1, to=1-2]
  \arrow["long label" overlay, no math, from=1-2, to=2-2]
  \arrow[from=1-1, to=2-1]
  \arrow[from=2-1, to=2-2]
\end{tikzcd}\]
Here is the second diagram again. The long label throws off the centering.

\textcolor{red}{→ Use \texttt{center matrix} (and \texttt{no math}).}
\[\begin{tikzcd}[center matrix, columns from center]
  A & B \\
  C & D
  \arrow[from=1-1, to=1-2]
  \arrow["long label", no math, from=1-2, to=2-2]
  \arrow[from=1-1, to=2-1]
  \arrow[from=2-1, to=2-2]
\end{tikzcd}\]
Here is the third diagram. It looks too wide.

\textcolor{red}{→ Use \texttt{between origins} \emph{carefully} for all diagrams.}
\[\begin{tikzcd}[columns from center]
  {A+E} & {B+E} \\
  {C+E} & {D+E}
  \arrow[from=1-1, to=1-2]
  \arrow[from=1-2, to=2-2]
  \arrow[from=1-1, to=2-1]
  \arrow[from=2-1, to=2-2]
\end{tikzcd}\]
\end{document}

Output

enter image description here

3
  • I didn't know about the possibility to use overlay this way, great! The column distribution is a solution much better than mine, but it looks ugly the same, I still prefer the standard behavoir.
    – CarLaTeX
    Commented Oct 31, 2022 at 15:08
  • @CarLaTeX Yes, aligning the columns can get messy real quick with diverse cells (wide ones and thin ones) and different number of columns. I don't recommend it either. But I also don't use CDs so maybe there's a good reason the two diagrams should have the same spacing. And maybe something like \(short)intertext would be helpful, i.e. interrupting the diagram for a bit of text? Commented Oct 31, 2022 at 16:14
  • Maybe, I don't use CDs, too.
    – CarLaTeX
    Commented Oct 31, 2022 at 16:19
3

For the problem of the label in the second diagram, in addition to what was suggested in the comments, you could also use the option text width=0pt (you'll get a warning but it's wanted) or create a box with no width \makebox[0pt][l]{$\text{long label}$}.

To shrink the third diagram you can modify the distance between the columns with &[-18pt] and also reduce the inner x-space of the nodes with [every cell/.append style={inner xsep=1pt}].
However, I find it very awful, much better to leave it as is.

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz-cd}
\begin{document}
\noindent Here is the first diagram.  
\[\begin{tikzcd}
A & B \\
C & D
\arrow[from=1-1, to=1-2]
\arrow[from=1-2, to=2-2]
\arrow[from=1-1, to=2-1]
\arrow[from=2-1, to=2-2]
\end{tikzcd}\]
For the problem of the label in the second diagram, you could also use the option \texttt{text width=0pt} or set a left aligned box of 0pt width:
\[\begin{tikzcd}
A & B \\
C & D
\arrow[from=1-1, to=1-2]
\arrow["{\text{long label}}"{text width=0pt}, from=1-2, to=2-2]
\arrow[from=1-1, to=2-1]
\arrow[from=2-1, to=2-2]
\end{tikzcd}\]
\[\begin{tikzcd}
A & B \\
C & D
\arrow[from=1-1, to=1-2]
\arrow["{\makebox[0pt][l]{$\text{long label}$}}", from=1-2, to=2-2]
\arrow[from=1-1, to=2-1]
\arrow[from=2-1, to=2-2]
\end{tikzcd}\]
To shrink the third diagram you can modify the distance between the columns with \texttt{\&[-18pt]} and also reduce the inner x-space of the nodes with \texttt{[every cell/.append style=\{inner xsep=1pt\}]}. 

However, I find it \emph{very awful!} Much better to leave it as is.
\[\begin{tikzcd}[every cell/.append style={inner xsep=1pt}]
{A+E} &[-18pt] {B+E} \\
{C+E} & {D+E}
\arrow[from=1-1, to=1-2]
\arrow[from=1-2, to=2-2]
\arrow[from=1-1, to=2-1]
\arrow[from=2-1, to=2-2]
\end{tikzcd}\]
\end{document}

enter image description here

You must log in to answer this question.

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