Countability of the rationals: a pictorial diagram
As Qrrbrbirlbel commented, you can use the \matrix
command. The matrix of math nodes
option from the matrix
library will save you some typing by automatically turning on math mode in each cell. When you name a matrix (m)
, you can use the syntax (m-i-j)
to refer to the cell in row i
and column j
of that matrix. To connect nodes, simply draw the edges after the matrix is set up.
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\begin{tikzpicture}
\matrix(m)[matrix of math nodes,column sep=1cm,row sep=1cm]{
s_{11} & s_{12} & s_{13} & s_{14} & \cdots \\
s_{21} & s_{22} & s_{23} & s_{24} & \cdots \\
s_{31} & s_{32} & s_{33} & s_{34} & \cdots \\
s_{41} & s_{42} & s_{43} & \cdots \\
};
\draw[->]
(m-1-1)edge(m-1-2)
(m-1-2)edge(m-2-1)
(m-2-1)edge(m-3-1)
(m-3-1)edge(m-2-2)
(m-2-2)edge(m-1-3)
(m-1-3)edge(m-1-4)
(m-1-4)edge(m-2-3)
(m-2-3)edge(m-3-2)
(m-3-2)edge(m-4-1);
\end{tikzpicture}
\end{document}
Here is a solution that draws the edges automatically; no need to specify them one by one!
You can make the graph as big as you wish: simply specify the number of nodes you want by changing the value of positive integer \N
.
Note: Failure to load the babel
package with the english
option will generate errors. See tikz-uml sequence diagram "Extra \or" error for more details.
Edit: See also Qrrbrbirlbel's "chains" solution, which is similar to mine in spirit.
\documentclass{article}
\usepackage[english]{babel}
\usepackage{etoolbox}
\usepackage{pgfplots}
\usetikzlibrary{arrows}
\begin{document}
\begin{tikzpicture}%
[
->,
>=stealth',
scale=2,
auto,
thick,
main node/.style=%
{
% circle,
% fill=blue!20,
% draw,
font=\sffamily\Large\bfseries,
}
]
\pgfmathtruncatemacro\N{10}
\pgfmathtruncatemacro\i{1}
\pgfmathtruncatemacro\j{1}
\node[main node] at (\j,-\i) (n1) {$S_{\i\j}$};
\pgfplotsforeachungrouped \current in {1,2,...,\N-1}%
{
\pgfmathtruncatemacro\next{\current+1}
\ifnum\i=1% (first row)
\ifnumodd{\j}%
{ % Go East
\pgfmathtruncatemacro\j{\j+1}
}{% Go South West
\pgfmathtruncatemacro\i{\i+1}
\pgfmathtruncatemacro\j{\j-1}
}
\else%
\ifnum\j=1% (first column)
\ifnumodd{\i}%
{ % Go North East
\pgfmathtruncatemacro\i{\i-1}
\pgfmathtruncatemacro\j{\j+1}
}{% Go South
\pgfmathtruncatemacro\i{\i+1}
}
\else
\pgfmathtruncatemacro{\ijsum}{\i+\j}
\ifnumodd{\ijsum}%
{ % Go South West
\pgfmathtruncatemacro\i{\i+1}
\pgfmathtruncatemacro\j{\j-1}
}{% Go North East
\pgfmathtruncatemacro\i{\i-1}
\pgfmathtruncatemacro\j{\j+1}
}
\fi
\fi
\node[main node] at (\j,-\i) (n\next) {$S_{\i\j}$};
\draw (n\current) -- (n\next);
}
\end{tikzpicture}
\end{document}
Matrix
It seems that a TikZ \matrix
is the easiest approach here.
Combined with the execute at empty cell
which fills the matrix automatically and the continous edges to
style, you can create this diagram very fast.
Though, the arrows follow a pattern which can be automated, too:
This is done with the keys matrix connector urr
(up-right, right) and matrix connector ldd
(left-down, down) which initial a search algorithm that relies on named nodes in the matrix.
Code
\documentclass[tikz,convert=false]{standalone}
\usetikzlibrary{matrix}
\makeatletter
\tikzset{
@continous edges to/.style={insert path={edge (#1) (#1)}},
continous edges to/.style={@continous edges to/.list={#1}},
matrix connector urr/.code args={#1-#2-#3}{%
\pgfutil@ifundefined{pgf@sh@ns@#1-\the\numexpr#2-1\relax-\the\numexpr#3+1\relax}{%
\pgfutil@ifundefined{pgf@sh@ns@#1-#2-\the\numexpr#3+1\relax}{}{
\tikzset{insert path={(#1-#2-#3) edge (#1-#2-\the\numexpr#3+1\relax)},
matrix connector ldd/.expanded={#1-#2-\the\numexpr#3+1\relax}}%
}%
}{%
\tikzset{insert path={(#1-#2-#3) edge (#1-\the\numexpr#2-1\relax-\the\numexpr#3+1\relax)},
matrix connector urr/.expanded={#1-\the\numexpr#2-1\relax-\the\numexpr#3+1\relax}}%
}
},
matrix connector ldd/.code args={#1-#2-#3}{%
\pgfutil@ifundefined{pgf@sh@ns@#1-\the\numexpr#2+1\relax-\the\numexpr#3-1\relax}{%
\pgfutil@ifundefined{pgf@sh@ns@#1-\the\numexpr#2+1\relax-#3}{}{%
\tikzset{insert path={(#1-#2-#3) edge (#1-\the\numexpr#2+1\relax-#3)},
matrix connector urr/.expanded={#1-\the\numexpr#2+1\relax-#3}}%
}%
}{%
\tikzset{insert path={(#1-#2-#3) edge (#1-\the\numexpr#2+1\relax-\the\numexpr#3-1\relax)},
matrix connector ldd/.expanded={#1-\the\numexpr#2+1\relax-\the\numexpr#3-1\relax}}%
}
},
}
\makeatother
\begin{document}
\begin{tikzpicture}
\matrix (m) [
matrix of nodes,
nodes={
shape=circle,
inner sep=+.1667em,% half the default value
},
execute at empty cell={\node {$S_{\the\pgfmatrixcurrentrow\the\pgfmatrixcurrentcolumn}$};},
row sep=2em,
column sep=2em
] {
& & & \\
& & & \\
& & & \\
& & & \\
};
\path[->, ultra thick, matrix connector urr={m-1-1}];
\path[->,white, shorten >=2\pgflinewidth] (m-1-1) [continous edges to={m-1-2, m-2-1, m-3-1, m-2-2, m-1-3, m-1-4, m-2-3, m-3-2, m-4-1}];
\end{tikzpicture}
\end{document}
Output
Chains
An alternative approach, similar to Jubobs' answer, can be implemented with the chains
library where one can use the placement options of the positioning
library (i.e. on grid
, node distance
) for greater control. It is only used to place the nodes that are connected.
Code
\documentclass[tikz,convert=false]{standalone}
\usetikzlibrary{chains}
\newcommand*{\subscript}[3][]{%
\ifodd#2
\the\numexpr#2+1-#3\relax#1#3%
\else
#3#1\the\numexpr#2+1-#3\relax
\fi}
\tikzset{
zigzag/.code 2 args={%
\ifnum#1>1
\ifodd#1
\ifnum#2=1
\def\position{below}%
\else
\def\position{above right}%
\fi
\else
\ifnum#2=1
\def\position{right}%
\else
\def\position{below left}%
\fi
\fi
\tikzset{\position=of \tikzchainprevious}
\fi
},
zigzag*/.code={%
\edef\llevel{\number\tikzchaincount}%
\pgfmathloop
\edef\testllevel{\the\numexpr\llevel-\pgfmathcounter\relax}%
\ifnum1>\testllevel\relax
\let\level\pgfmathcounter
\else
\let\llevel\testllevel
\repeatpgfmathloop
\tikzset{zigzag=\level\llevel}%
}
}
%
\tikzset{
every label/.append style={inner sep=+0pt, outer sep=+0pt, font=\tiny},
label position=above left,
every join/.append style={-latex},
}
\begin{document}
\begin{tikzpicture}[
start chain=ch going {zigzag=\level\llevel},
node distance=.75cm and 1cm,
every on chain/.append style={
join, label={(\number\tikzchaincount)}}]
\foreach \level in {1,...,4}
\foreach \llevel in {1,...,\level}
\node[on chain=ch] {$S_{\subscript[,]\level\llevel}$};
\end{tikzpicture}
\begin{tikzpicture}[
on grid, node distance=1cm and 1.5cm, start chain=ch placed zigzag*,
every on chain/.append style={
circle, inner sep=+.1667em, text depth=+0pt, text height=+1.5ex,
join, label/.expanded={(\noexpand\subscript[/]{\level}{\llevel})}}]
\foreach \cnt in {a,...,f} \node[on chain=ch] {\cnt};
\foreach \cnt in {G,...,M} \node[on chain=ch] {\cnt};
\end{tikzpicture}
\end{document}