39

I just read a book "Linear Algebra and Its Applications 4E" by David C. Lay. The book is (should be) LaTeX typeset. The matrix and equations are so nice, please see the following 3 examples:

enter image description here

enter image description here

enter image description here

It's so beautiful, so I want get the same effect inside my paper. Here is my code:

\usepackage{amsmath}
\usepackage{colortbl}
\newcommand\y{\cellcolor{clight2}}
\definecolor{clight2}{RGB}{212, 237, 244}%

%%%
\[A=\left[
\begin{array}{ccccc}
\y 0 & -3 & -6 & 4 & 9 \\   
-1 & \y -2 & -1 & 3 & 1 \\
-2 & -3 & 0 & \y 3 & -1 \\
1 & 4 & 5 & -9 & -7     
\end{array}
\right]\]

\[A=\left[\begin{array}{cccccc}
\rowcolor{clight2}
3 & -9 & 12 & -9 & 6 & 15\\
0 & 2 & -4 & 4 & 2 & -6 \\
0 & 3 & -6 & 6 & 4 & -5
\end{array}
\right]\]

And the result:

enter image description here

But how to add these arrows??

2

3 Answers 3

57

Use the command

\tikznode[..options..]{..label..}{..contents..}

to mark the contents that the arrows should point to. To add arrows and text, use

\begin{tikzpicture}[remember picture,overlay]
  ... tikz code using the labels defined by \tikznode ...
\end{tikzpicture}

Define the command \tikznode in the preamble as

\usepackage{tikz}
\newcommand\tikznode[3][]%
   {\tikz[remember picture,baseline=(#2.base)]
      \node[minimum size=0pt,inner sep=0pt,#1](#2){#3};%
   }

You have to run LaTeX at least twice until the information about the positions has propagated everywhere.

enter image description here

\documentclass{article}
\usepackage{tikz}
\usepackage{amsmath}
\usepackage{colortbl}
\newcommand\y{\cellcolor{clight2}}
\definecolor{clight2}{RGB}{212, 237, 244}%
\newcommand\tikznode[3][]%
   {\tikz[remember picture,baseline=(#2.base)]
      \node[minimum size=0pt,inner sep=0pt,#1](#2){#3};%
   }
\tikzset{>=stealth}
\renewcommand\vec[1]{\mathbf{#1}}
\begin{document}
%%%
\[A=\left[
\begin{array}{rrrrr}
\y \tikznode{pp1}{$0$} & -3 & -6 & 4 & 9 \\   
-1 & \y -\tikznode{pp2}{$2$} & -1 & 3 & 1 \\
-2 & -3 & 0 & \y \tikznode{pp3}{$3$} & -1 \\
\tikznode{pc1}{$1$} & \tikznode{pc2}{$4$} & 5 & -\tikznode{pc3}{$9$} & -7     
\end{array}
\right]\]
\vspace{3ex}

\[A=\left[\begin{array}{rrrrrr}
\rowcolor{clight2}
3 & -9 & 12 & -9 & 6 & 15\\
0 & \tikznode{piv}{$2$} & -4 & 4 & 2 & -6 \\
0 & \tikznode{npc}{$3$} & -6 & 6 & 4 & -5
\end{array}
\right]\]
\vspace{3ex}

\[\tikznode{u1v1}{$(u_1+v_1)$}\tikznode{a1}{$\vec a_1$}
  + \tikznode{u2v2}{$(u_2+v_2)$}\tikznode{a2}{$\vec a_2$}
\]

\begin{tikzpicture}[remember picture,overlay,cyan,rounded corners]
  % explicit coordinates are relative to the end of arrow,
  % they do not accumulate (note the single + preceding the coords)
  % "Pivot positions"
  \draw[<-,shorten <=1pt] (pp1)
    -- +(0.4,0)% short line to the right
    |- +(4,0.4)% short up and long right
    coordinate (pp)% remember position for other arrows
    node[right] {Pivot positions};
  \draw[<-,shorten <=1pt] (pp2)
    -- +(0.4,0)% short line to the right
    |- (pp);% up and right to pp
  \draw[<-,shorten <=1pt] (pp3)
    -- +(0.4,0)% short line to the right
    |- (pp);% up and right to pp
  % "Pivot columns"
  \draw[<-,shorten <=2pt] (pc1)
    -- +(0,-0.5)% short line down
    coordinate (pc1')% remember position for computing next coord
    -- (pc1'-|pp)% horizontal line to position right of pc1' and below of pp
    coordinate (pcs)% remember position for other arrows
    node[right] {Pivot columns};
  \draw[<-,shorten <=2pt] (pc2)
    |- (pcs);% down and right to pcs
  \draw[<-,shorten <=2pt] (pc3)
    |- (pcs);% down and right to pcs
  % "Pivot"
  \draw[<-,shorten <=1pt] (piv)
    -- +(0.4,0)% short line to the right
    |- +(1,0.8)% up and right
    node[right] {Pivot};
  % "New Pivot column"
  \draw[<-,shorten <=2pt] (npc)
    |- +(1,-0.5)% down and right
    node[right] {New Pivot column}; 
  % "Entries in u+v"
  \draw[<-] (u1v1)
    |- +(4,0.5)% short up and long right
    coordinate (uv)% remember position for other arrow and other label
    node[right]{Entries in $\vec u+\vec v$};
  \draw[<-] (u2v2)
    |- (uv);% up and right to uv
  % "Columns of A"
  \draw[<-] (a1)
    -- +(0,-0.5)% short line down
    coordinate (a1')% name position for computing next coord
    -- (a1'-|uv)% horizontal line to position right of a1' and below of uv
    coordinate (a)% remember position for other arrow
    node[right]{Columns of $A$};
  \draw[<-] (a2)
   |- (a);% down and right to a
\end{tikzpicture}
\end{document}

If you prefer pointed corners like in the original, remove the option rounded corners.

enter image description here

13
  • 9
    +1. Your \tikznode should become a feature of \tikzmark package!
    – CarLaTeX
    Commented Mar 31, 2017 at 16:34
  • @gernot What should I change if I want multiple matrices in the same line, uncentered and not different lines, each centered?
    – reyna
    Commented Apr 16, 2020 at 7:36
  • 1
    @zaira I don't completely understand what you want to achieve. My impression is that it is unrelated to adding arrows. Once you have figured out how to arrange the matrices, you can add arrows as described above. I suggest that you post a separate question with a sketch showing the desired arrangement of matrices. You may also take a look at the answers to maybe related problems, like tex.stackexchange.com/q/9901/110998, tex.stackexchange.com/q/145952/110998, tex.stackexchange.com/q/74443/110998,
    – gernot
    Commented Apr 16, 2020 at 9:00
  • @gernot I had trouble with alignment, actually. Instead of centre, I wanted them to be left aligned but I have figured out a way. Thanks!
    – reyna
    Commented Apr 16, 2020 at 10:05
  • 1
    Very nice indeed. Out of my mind....
    – Mikasa
    Commented Jan 31, 2023 at 16:18
6

For the pictures with the matrices, you can draw the arrows with Tikz by using the Tikz nodes created by {bNiceMatrix} of nicematrix.

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

\begin{document}

$A = 
\begin{bNiceMatrix}[margin,r]
\CodeBefore
  \cellcolor{cyan!15}{1-1,2-2,3-4}
\Body
0  & -3 & -6 & 4  & 9  \\
-1 & -2 & -1 & 3  & 1  \\
-2 & -3 & 0  & 3  & -1 \\
1  & 4  & 5  & -9 & -7 \\
\CodeAfter
  \begin{tikzpicture} [cyan,<-]
  \draw (1-1.east) -| ([xshift=1mm,yshift=2mm]1-|2) 
                   -- ([yshift=2mm]1-|last) -- ++(5mm,0) node [right] {Pivot positions} ; 
  \draw (2-2.east) -| ([xshift=1mm,yshift=2mm]1-|3) ; 
  \draw (3-4.east) -| ([xshift=1mm,yshift=2mm]1-|5) ; 
  \draw (4-1.south) ++(0,-2pt) |- ([yshift=-2mm]5-|last) -- ++(5mm,0) node [right] {Pivot columns} ;
  \draw (4-2.south) ++(0,-2pt) |- ([yshift=-2mm]5-|4-2) ;
  \draw (4-4.south) ++(0,-2pt) |- ([yshift=-2mm]5-|4-4) ;
  \end{tikzpicture}
\end{bNiceMatrix}$

\end{document}

You need several compilations (because nicematrix uses PGF/Tikz nodes under the hood).

Output of the above code

2
  • You are the master of nicematrix
    – MadyYuvi
    Commented Nov 5, 2021 at 14:16
  • 1
    @MadyYuvi He is the creator and the maintainer of nicematrix !
    – AndréC
    Commented Nov 5, 2021 at 16:13
2

The existing answers focus primarily on the matrix part of the question. In this answer, I'm going to focus on the equation. Although this is in gernot's answer, it is missing a crucial feature: spacing relative to the rest of the mathematics.

For this, I use the tikzmark TikZ library. Tikzmark has evolved considerably since its first appearance in http://tex.stackexchange.com/a/316/86 (in 2010) where in its initial form it was very similar to the command \tikznode that gernot uses in their answer. In the intervening decade, it split into two parts: \tikzmark, which focusses on just remembering a position, and \tikzmarknode, which is based on the original command but with added extras such as detecting the current math mode.

To get the spacing right, we need both. We use \tikzmarknode to mark the relevant parts of the equation. Then in a later tikzpicture we place the annotation nodes at their correct places relative to the equation. We also use \tikzmark (which can work both inside and outside a tikzpicture environment) to remember certain locations inside this tikzpicture. These locations are then used earlier to set the spacing of the annotated line.

There is a subtlety here. This all relies on locations of pieces of the page being written out to the aux file and then read back in on the next run. So each time, the locations are actually one compilation out of date. This can lead to bits of text jumping around and never settling down. In particular, if the location of A depends on the previous position of B, and that of B on the previous position of A then it can end up in a loop. The solution is to build in a level of relative positioning. So that instead of B depending on the previous position of A, it depends on the previous position of A relative to some other point that is chosen to avoid the loop.

Here's the code:

\documentclass{article}
%\url{https://tex.stackexchange.com/q/361375/86}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{tikzmark,calc,arrows.meta}

\let\vec=\mathbf

\begin{document}

\begin{align*}
A(\vec{u} + \vec{v}) &=
\begin{bmatrix} \vec{a}_1 & \vec{a}_2 & \vec{a}_3 \end{bmatrix}
\begin{bmatrix} u_1 + v_1 \\ u_2 + v_2 \\ u_3 + v_3 \end{bmatrix} \\
%
% The various `\tikzmarknode`s here allow us to refer back to these
% terms
&= \tikzmarknode{uv1}{(u_1 + v_1)} \tikzmarknode{a1}{\vec{a}_1} +
\tikzmarknode{uv2}{(u_2 + v_2)} \tikzmarknode{a2}{\vec{a}_2} +
\tikzmarknode{uv3}{(u_3 + v_2)} \tikzmarknode{a3}{\vec{a}_3}
% This is a bit like a vertical strut; it ensures that there is enough
% vertical space for the annotations
\tikz[remember picture,baseline={(0,0)}] {\path let \p1=(pic cs:upper), \p2=(pic cs:lower), \p3=(pic cs:middle) in (0,\y1-\y3) (0,\y2-\y3);}
\\
%
&= (u_1 \vec{a}_1 + u_2 \vec{a}_2 + u_3 \vec{a}_3) +
(v_1 \vec{a}_1 + v_2 \vec{a}_2 + v_3 \vec{a}_3) \\
%
&= A \vec{u} + A \vec{v}
\end{align*}

\begin{tikzpicture}[remember picture, overlay,>=Latex, cyan]
% locate the annotations
\node[above right] (entries) at ($(a3.north east)+(1,.5)$) {Entries in \(\vec{u} + \vec{v}\)};
\node[below right] (columns) at ($(a3.south east)+(1,-.5)$) {Columns of \(A\)};
% Draw the lines
\draw[<-,rounded corners] (uv1.north) |- (entries);
\draw[<-,rounded corners] (uv2.north) |- (entries);
\draw[<-,rounded corners] (uv3.north) |- (entries);
\draw[<-,rounded corners] (a1.south) |- (columns);
\draw[<-,rounded corners] (a2.south) |- (columns);
\draw[<-,rounded corners] (a3.south) |- (columns);
% These three are used mark the extent of the annotations
% Although a3.base is in the same place as the tikzmark a3, these
% three tikzmarks need to be all defined in the same tikzpicture
% so that their *relative* positions are always the same
\tikzmark{upper}{(entries.north)}
\tikzmark{lower}{(columns.south)}
\tikzmark{middle}{(a3.base)}
\end{tikzpicture}


\end{document}

Here's the result:

Using tikzmark to space out lines in an annotated equation

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .