4

I would like to reproduce a table in tikz with arrows from predefined cell to another predefined cell.

Something looks like this.

enter image description here

What I did was the following:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,matrix,positioning}

\tikzset{ 
    table/.style={
        matrix of nodes,
        row sep=-\pgflinewidth,
        column sep=-\pgflinewidth,
        nodes={rectangle,text width=3em,align=center},
        text depth=1.25ex,
        text height=2.5ex,
        nodes in empty cells
    },
}
\begin{document}
  \begin{tikzpicture}
    % the matrix entries
    \matrix (mat) [table]
    {
    & $x$ & $y$ & $z$ \\
    $x$ & a  & a & b \\
    $y$ & b & a & c \\
    $z$ & c & d & e \\
    };
    % the matrix rules
    \foreach \x in {1,...,3}
    {
      \draw 
        ([xshift=-.5\pgflinewidth]mat-\x-1.south west) --   
        ([xshift=-.5\pgflinewidth]mat-\x-4.south east);
      }
    \foreach \x in {1,...,3}
    {
      \draw 
        ([yshift=.5\pgflinewidth]mat-1-\x.north east) -- 
        ([yshift=.5\pgflinewidth]mat-4-\x.south east);
    }    
    % the arrows
    \begin{scope}[shorten >=7pt,shorten <= 7pt]
    \draw[->]  (mat-4-4.center) -- (mat-3-4.center);
    \draw[->]  ([shift={(2.5pt,3pt)}]mat-4-4.center) -- ([shift={(2.5pt,2.5pt)}]mat-2-4.center);
    \draw[->]  ([shift={(8pt,8pt)}]mat-2-4.center) -- ([shift={(8pt,8pt)}]mat-2-3.center);
    \end{scope}
    \end{tikzpicture}
\end{document}

But as you can see by reproducing the output of the above code, the arrows are note good in the sense that are not aligned.

Note: Some of the above code was found in this site but I can't remember exactly the link.

EDIT: Here is the output of my code:

enter image description here

2 Answers2

10

Using a normal tabular along with the tikzmark library would be much easier. After marking the required positions and giving names for them, using \tikzmark{<a name>}, then comes a tikzpicture to draw the actual arrows as given below. Fine tuning may be required to get the best result.

\documentclass[border=5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\begin{document}

\renewcommand{\arraystretch}{1.5}
\begin{tabular}{c|c|c|c}
        & $x$ & $y$ & $z$ \\ \hline
    $x$ & a   & a\tikzmark{a}   & b\tikzmark{b}   \\ \hline
    $y$ & b   & a   & \tikzmark{c}c  \\ \hline
    $z$ & c   & d   & \tikzmark{e}e\tikzmark{ee}   \\
\end{tabular}

\begin{tikzpicture}[overlay,remember picture, shorten >=-3pt]
\draw[->,yshift=2ex] (pic cs:b) -- (pic cs:a) ;
\draw[->,xshift=-.7ex] (pic cs:e) -- (pic cs:c);
\draw[->,xshift=0.7ex] (pic cs:ee) -- (pic cs:b);
\end{tikzpicture}

\end{document}

enter image description here

AboAmmar
  • 46,352
  • 4
  • 58
  • 127
0

With {NiceTabular} and TikZ to draw the arrows.

\documentclass{article}
\usepackage{nicematrix,tikz}

\begin{document}

\renewcommand{\arraystretch}{1.5} \begin{NiceTabular}{cccc}[hvlines-except-borders,create-medium-nodes] & $x$ & $y$ & $z$ \ $x$ & a & a & b \ $y$ & b & a & c \ $z$ & c & d & e \CodeAfter \begin{tikzpicture} [->, name suffix=-medium] \draw ([xshift=-1mm]4-4.south west) -- ([xshift=-1mm]3-4.west) ; \draw ([xshift=1mm]4-4.south east) -- ([xshift=1mm]2-4.east) ;
\draw ([yshift=0.5mm]2-4.north east) -- ([yshift=0.5mm]2-3.north) ; \end{tikzpicture} \end{NiceTabular}

\end{document}

Output of the above code

F. Pantigny
  • 40,250