3

I have the following code:

\documentclass[11pt]{article} 

\usepackage[utf8]{inputenc} 

\usepackage{geometry} 
\geometry{a4paper} 
\usepackage{tikz} 
\usetikzlibrary{matrix}
\usetikzlibrary{calc}


\begin{document}


\begin{center}
\begin{tikzpicture}
\draw[step=2cm,color=gray] (-4.001,-6.001) grid (6,4);
\matrix[matrix of nodes,inner sep=1cm, nodes={align=center}]{
A & B & C & D & E \\
A & B & C & D & E \\
A & B & C & D & E \\
A & B & C & D & E \\
A & B & C & D & E \\};

\foreach \y in {-3, -2, -1, 0, 1, 2}
    \draw ($(-5, 2*\y)$) -- ($(-5, 2*\y)$) node {$\y$};
\foreach \x in {-2, -1, 0, 1, 2, 3}
    \draw ($(2*\x, 5)$) -- ($(2*\x, 5)$) node {$\x$};


\foreach \x in {-4, -2, 0, 2, 4, 6} {
  \foreach \y in {-6, -4, -2, 0, 2, 4}  {
    \node[draw,circle,inner sep=2pt,fill] at (\x,\y) {};
   }
}
\end{tikzpicture}
\end{center}


\end{document}

And I am trying to align the matrix such that each element of 0, A, B, ..., E is in the center of a square, but I am not able to get this to work. I don't understand why 'column sep' shifts the terms more and more.

Thanks!

  • 1
    column sep={2cm,between origins}? Isn't ($(-3, \y) + (-2, \y)$) just (-5, 2*\y)? Can you complete your example to a full MWE and show what you want to achieve? I’d use only matrix for this, though. – Qrrbrbirlbel Jun 3 '15 at 17:37
  • Hi Qrrbrbirlbel! I've updated my post with a MWE. When you run the code you will get a grid. I want the elements in the matrix to be aligned such that each element is in it's respective square. So the top most-left square should have an 'A' and the bottom most-right square should contain an 'E'. I also want these elements to be centered in the square. – tolog Jun 3 '15 at 17:58
  • Does this help? tex.stackexchange.com/questions/191239/… – JPi Jun 3 '15 at 18:05
  • Thanks! I added every node/.style={anchor=base,text depth=-1cm,text height=1cm,text width=0cm} in \matrix[{INSERT HERE}] and it seems to be working. After further investigation it seems like what I needed was text width=0cm (and also height) – tolog Jun 3 '15 at 18:17
3

I would do it completely with a matrix. If you set the nodes to

draw=gray, minimum size=+1cm, outer sep=+0pt, text depth=+-.5ex, text height=+1ex

you get a grid-like set of boxes. The column sep and row sep needs to bet set to -\pgflinewidth so that the nodes overlap.

The dots can then be added via two \foreach loops:

\foreach \row in {1,...,4}{
  \foreach \column in {1,...,6}
    \node at (m-\row-\column.north west) [dot]
     [if={\row==4}{insert path=node at (m-\row-\column.south west) [dot]}{}];
  \node at (m-\row-6.north east)[dot];
}
\node at (m-4-6.south east)[dot];

(This only adds one dot at each corner. Simpler loops can be constructed, they however add multiple dots at most corners.)

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}[
  dot/.style={fill,circle, inner sep=+0pt, minimum size=+4pt, node contents=},
]
\matrix[matrix of nodes, nodes in empty cells,
  column sep=-\pgflinewidth, row sep=-\pgflinewidth,
  nodes={draw=gray, minimum size=+1cm, outer sep=+0pt,
  text depth=+-.5ex, text height=1ex}
  ] (m) {
0 & A & B & C & D & E \\
  &   &   &   &   &   \\
  &   &   &   &   &   \\
  &   &   &   &   &   \\
};
\foreach \row in {1,...,4}{
  \foreach \column in {1,...,6}
    \node at (m-\row-\column.north west) [dot]
     [if={\row==4}{insert path=node at (m-\row-\column.south west) [dot]}{}];
  \node at (m-\row-6.north east)[dot];
}
\node at (m-4-6.south east)[dot];
\end{tikzpicture}
\end{document}

If you are feeling more adventurous, you can add these dots as part of labels of the matrix’s nodes. This needs, however, two fixes:

  • An override of the automatically selected anchor for the labels,
    see How can I set the TikZ label anchor explicitly?
  • As labels are nodes themselved, they also get the every node style applied. If we add those dots as labels to the every node style we would get an infinite amount of recursion. (Every label would get labels which get labels …)

    For this I introduce the not if label key which argument will only get applied if the node it is used in is not a label. (For a pin a similar key can be constructed.)

Unfortunately, the labels will count to a cell’s dimension, so you will either need to accommodate their sizes into the column sep and row sep or add overlay to the dot style. This might make them protrude outside of the picture if the inner seps of the matrix is smaller than half the size of the dots.

Again, the addition of the dots is done so that every dot is only drawn once.

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{matrix}
\makeatletter
\tikzset{not if label/.code={%
    \pgfutil@ifundefined{tikz@save@last@fig@name}{\pgfkeysalso{#1}}{}}}
\makeatother
\tikzset{
  label anchor/.style={tikz@label@post/.append style={anchor=#1}},
  label dots/.style={label={[dot,label anchor=center]#1:}},
  nw dots/.style={label dots=north west},
  sw dots/.style={label dots=south west},
  ne dots/.style={label dots=north east},
  se dots/.style={label dots=south east}}
\begin{document}
\begin{tikzpicture}[
  dot/.style={fill,circle, inner sep=+0pt, minimum size=+4pt, overlay},
]
\matrix[matrix of nodes, nodes in empty cells,
  column sep=-\pgflinewidth, row sep=-\pgflinewidth,
  nodes={not if label={
    nw dots, draw=gray, minimum size=+1cm,
    outer sep=+0pt, text depth=+-.5ex, text height=1ex}},
  column 6/.style      ={nodes={not if label=ne dots}},
  row 4/.style         ={nodes={not if label=sw dots}},
  row 4 column 6/.style={nodes={not if label=se dots}},
  ]{
0 & A & B & C & D & E \\
  &   &   &   &   &   \\
  &   &   &   &   &   \\
  &   &   &   &   &   \\
};
\end{tikzpicture}
\end{document}

Output

enter image description here

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.