TikZ-CD – Creating Uniform Diagrams with Proper Spacing and Alignment

alignmentspacingtikz-cd

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}

Best Answer

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