# tikz matrix alignment problem

I'm trying to draw a explanation of SAD (Sum of Absolute differences). After a lot of tweaking I have something that sort of looks OK except that the horizontal as well as the vertical alignment/distances are terrible! And, as you can see, everything is hardcoded.

How can I get everything to line up beautifully?

Label Right which isn't aligned with Left and Center as well as the vertical distance between the 3 "rows". The Left, Center & Right matrixes should probably be moved to the right a bit to have everything centered on some imaginary vertical axis. To add a offset repetable until it looks better is a pain since there are many values to change, e.g. for the grids.

Output:

MWE:

\documentclass[convert={density=300,size=640x480,outext=.png}]{standalone}
\usepackage[english]{babel}
\usepackage[latin1]{inputenc}
\usepackage{times}
\usepackage[T1]{fontenc}

\usepackage{tikz}
\usetikzlibrary{calc, matrix}

\begin{document}

\begin{tikzpicture}
\draw[step=0.5cm,color=lightgray] (-.75,-.75) grid (.75,.75);
\matrix (template) [matrix of nodes,nodes={inner sep=0pt,text width=.5cm,align=center,minimum height=.5cm}]{
2 & 5 & 5 \\
4 & 0 & 7 \\
7 & 5 & 9 \\
};
\node[label={[xshift=0cm, yshift=0cm]Template}] at (template.north) {};

\draw[step=0.5cm,color=lightgray] (1.75,-.75) grid (4.25,.75);
\matrix (search) [matrix of nodes,nodes={inner sep=0pt,text width=.5cm,align=center,minimum height=.5cm}] at (3,0){
2 & 7 & \node[red]{5}; & \node[red]{8}; & \node[red]{6}; \\
1 & 7 & \node[red]{4}; & \node[red]{2}; & \node[red]{7}; \\
8 & 4 & \node[red]{6}; & \node[red]{8}; & \node[red]{5}; \\
};
\node[label={Search Image}] at (search.north) {};

\draw[step=0.5cm,color=lightgray] (-1.75,-3.75) grid (-.25,-2.25);
\matrix (left) [matrix of nodes,nodes={inner sep=0pt,text width=.5cm,align=center,minimum height=.5cm}] at (-1,-3){
0 & 2 & 0 \\
3 & 7 & 3 \\
1 & 1 & 3 \\
};
\node[label={Left}] at (left.north) {};

\draw[step=0.5cm,color=lightgray] (.25,-3.75) grid (1.75,-2.25);
\matrix (center) [matrix of nodes,nodes={inner sep=0pt,text width=.5cm,align=center,minimum height=.5cm}] at (1,-3){
5 & 0 & 3 \\
3 & 4 & 5 \\
3 & 1 & 1 \\
};
\node[label={Center}] at (center.north) {};

\draw[step=0.5cm,color=lightgray] (2.25,-3.75) grid (3.75,-2.25);
\matrix (right) [matrix of nodes,nodes={inner sep=0pt,text width=.5cm,align=center,minimum height=.5cm}] at (3,-3){
\node[red]{3}; & \node[red]{3}; & \node[red]{1}; \\
\node[red]{0}; & \node[red]{2}; & \node[red]{0}; \\
\node[red]{1}; & \node[red]{3}; & \node[red]{4}; \\
};
\node[label={Right}] at (right.north) {};

\matrix (sad) [matrix of nodes] at (1,-5) {
20 & 25 & \node[red]{17}; \\
};
% ..
\end{tikzpicture}
\end{document}

-
Please elaborate on exactly what you mean by "line up beautifully". Also, while code snippets are useful in explanations, it is always best to compose a fully compilable MWE that illustrates the problem including the \documentclass and the appropriate packages so that those trying to help don't have to recreate it. –  Peter Grill Apr 24 '14 at 20:27
sorry, updated MWE. I mainly thought about the label Right which isn't aligned with Left and Center as well as the vertical distance between the 3 "rows" –  Fredrik Pihl Apr 24 '14 at 20:32

Here is a very different version, where no positions are explicit. The center matrix is defined first, and the other placed relative to this. This gives a consistent distance between (the edges) of the matrices. You can modify the spacing by changing the node distance key that I added to the tikzpicture options. The first value is the vertical spacing, the second is the horizontal. The positioning library is added to allow this type of positioning.

The vertical alignment of Right is fixed by adding a text depth to each of the label nodes (similar to Comma alignment problem).

To add options to a node in a matrix of nodes you can add |[<options>]| to the beginning of the cell. I used this to make the some values |[red]|. (In hindsight: For the right matrix you could just add red to the matrix options instead. For search you could also modify the column 3/column 4/column 5 styles, instead of modifying each cell in those columns.)

I also added a couple of styles, to reduce code repetition.

The grids are drawn after the matrices, but on the background layer with the help of the backgrounds library.

\documentclass[convert={density=300,size=640x480,outext=.png}]{standalone}
\usepackage[english]{babel}
\usepackage[latin1]{inputenc}
\usepackage{times}
\usepackage[T1]{fontenc}

\usepackage{tikz}

\usetikzlibrary{calc, matrix, positioning,backgrounds}

\begin{document}
\begin{tikzpicture}[
node distance=1cm and 0.5cm,
matrixlabel/.style={text depth=3pt,above},
matrixnodes/.style={inner sep=0pt,text width=.5cm,align=center,minimum height=.5cm}]

\matrix (center)
[matrix of nodes,
nodes={matrixnodes}]{
5 & 0 & 3 \\
3 & 4 & 5 \\
3 & 1 & 1 \\
};
\node [matrixlabel] at (center.north) {Center};

\matrix (right)
[matrix of nodes,
nodes={matrixnodes},
right=of center]  {
|[red]| {3} & |[red]| 3 & |[red]| 1 \\
|[red]| 0 & |[red]| 2 & |[red]| 0 \\
|[red]| 1 & |[red]| 3 & |[red]| 4 \\
};
\node [matrixlabel] at (right.north) {Right};

\matrix (left)
[matrix of nodes,
nodes={matrixnodes},
left=of center] {
0 & 2 & 0 \\
3 & 7 & 3 \\
1 & 1 & 3 \\
};
\node [matrixlabel] at (left.north) {Left};

\matrix (template)
[matrix of nodes,
nodes={matrixnodes},
above=of left.north west,
anchor=south west] {
2 & 5 & 5 \\
4 & 0 & 7 \\
7 & 5 & 9 \\
};
\node[matrixlabel] at (template.north) {Template};

\matrix (search)
[matrix of nodes,
nodes={matrixnodes},
above=of right.north east,
anchor=south east] {
2 & 7 & |[red]| 5 & |[red]| 8 & |[red]| 6 \\
1 & 7 & |[red]| 4 & |[red]| 2 & |[red]| 7 \\
8 & 4 & |[red]| 6 & |[red]| 8 & |[red]| 5 \\
};
\node[matrixlabel] at (search.north) {Search Image};

[matrix of nodes,
below=of center]  {
20 & 25 & |[red]| 17 \\
};

\begin{scope}[on background layer,lightgray]
\foreach \mat in {template, left, center, right} {
\foreach \i in {1,2,3} {
\draw  (\mat-\i-1.west) -- (\mat-\i-3.east);
\draw  (\mat-1-\i.north) -- (\mat-3-\i.south);
}
}

\foreach \i in {1,2,...,5}
\draw  (search-1-\i.north) -- (search-3-\i.south);
\foreach \i in {1,2,3}
\draw  (search-\i-1.west) -- (search-\i-5.east);
\end{scope}

\end{tikzpicture}
\end{document}

-
Beautiful. Thanks for the lesson, I learnt a lot! –  Fredrik Pihl Apr 25 '14 at 7:17

You can use scope environment and with xshift parameter:

\documentclass[convert={density=300,size=640x480,outext=.png}]{standalone}
\usepackage[english]{babel}
\usepackage[latin1]{inputenc}
\usepackage{times}
\usepackage[T1]{fontenc}

\usepackage{tikz}
\usetikzlibrary{calc, matrix}

\begin{document}

\begin{tikzpicture}
\draw[step=0.5cm,color=lightgray] (-.75,-.75) grid (.75,.75);
\matrix (template) [matrix of nodes,nodes={inner sep=0pt,text width=.5cm,align=center,minimum height=.5cm}]{
2 & 5 & 5 \\
4 & 0 & 7 \\
7 & 5 & 9 \\
};
\node[label={[xshift=0cm, yshift=0cm]Template}] at (template.north) {};

\draw[step=0.5cm,color=lightgray] (1.75,-.75) grid (4.25,.75);
\matrix (search) [matrix of nodes,nodes={inner sep=0pt,text width=.5cm,align=center,minimum height=.5cm}] at (3,0){
2 & 7 & \node[red]{5}; & \node[red]{8}; & \node[red]{6}; \\
1 & 7 & \node[red]{4}; & \node[red]{2}; & \node[red]{7}; \\
8 & 4 & \node[red]{6}; & \node[red]{8}; & \node[red]{5}; \\
};
\node[label={Search Image}] at (search.north) {};

\begin{scope}[xshift=0.75cm]
\draw[step=0.5cm,color=lightgray] (-1.75,-3.75) grid (-.25,-2.25);
\matrix (left) [matrix of nodes,nodes={inner sep=0pt,text width=.5cm,align=center,minimum height=.5cm}] at (-1,-3){
0 & 2 & 0 \\
3 & 7 & 3 \\
1 & 1 & 3 \\
};

\node[label={Left}] at (left.north) {};

\draw[step=0.5cm,color=lightgray] (.25,-3.75) grid (1.75,-2.25);
\matrix (center) [matrix of nodes,nodes={inner sep=0pt,text width=.5cm,align=center,minimum height=.5cm}] at (1,-3){
5 & 0 & 3 \\
3 & 4 & 5 \\
3 & 1 & 1 \\
};
\node[label={Center}] at (center.north) {};

\draw[step=0.5cm,color=lightgray] (2.25,-3.75) grid (3.75,-2.25);
\matrix (right) [matrix of nodes,nodes={inner sep=0pt,text width=.5cm,align=center,minimum height=.5cm}] at (3,-3){
\node[red]{3}; & \node[red]{3}; & \node[red]{1}; \\
\node[red]{0}; & \node[red]{2}; & \node[red]{0}; \\
\node[red]{1}; & \node[red]{3}; & \node[red]{4}; \\
};
\node[label={Right}] at (right.north) {};

\matrix (sad) [matrix of nodes] at (1,-5) {
20 & 25 & \node[red]{17}; \\
};
\end{scope}