11

I'd like to draw vertical/horizontal lines over the entries of a column/row in an array. I find the method to draw horizontal lines at Draw a horizonal line over the entries of a row in an array. But when I used the same way to draw the vertical lines. It didn't look well. My codes are:

\usepackage{tikz}
\usetikzlibrary{calc}
\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}
\newcommand{\DrawLine}[3][]{%
\begin{tikzpicture}[overlay,remember picture]
    \draw [#1] ($(#2)+(0,0.6ex)$) -- ($(#3)+(0,0.6ex)$);
\end{tikzpicture}%
}%

\begin{displaymath}
\left[
\begin{array}{cccc}
\tikzmark{11}{15} & 0 & \tikzmark{13}{0} &0\tikzmark{14} \\
0 & 50 & 20 & 25 \\
35 & 5 & 0 & 10\\
\tikzmark{41}{0} & 65 & \tikzmark{43}{50} & 65
\end{array}
\right].
\DrawLine[black,thick]{11}{14}
\DrawLine[black,thick]{11}{41}
\DrawLine[black,thick]{13}{43}
\end{displaymath}

The result looks like

enter image description here

But the result I want is

enter image description here

Does anyone know how to fix this? Thank you.

5 Answers 5

9

Here is an adaption of Draw a line through one column of a matrix:

enter image description here

Notes:

  • This does require two runs. First one to determine the locations, and the second to do the drawing.
  • Another option is to use the tikzmark package, but for this particular case it is simpler to not use that package: The custom defined \MyTikzmark provides anchor points .north and .south which are automatically centered vertically. Similarly .east and .west are centered vertically. In the tikzmark package version the lines were extended via shorten >= and shorten <= and shifted using yshift to provide similar results.

Code: Without tikzmark package.

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}

\newcommand{\MyTikzmark}[2]{%
     \tikz[overlay,remember picture,baseline] \node [anchor=base] (#1) {$#2$};%
}

\newcommand{\DrawVLine}[3][]{%
  \begin{tikzpicture}[overlay,remember picture]
    \draw[shorten <=0.3ex, #1] (#2.north) -- (#3.south);
  \end{tikzpicture}
}

\newcommand{\DrawHLine}[3][]{%
  \begin{tikzpicture}[overlay,remember picture]
    \draw[shorten <=0.2em, #1] (#2.west) -- (#3.east);
  \end{tikzpicture}
}


\begin{document}
\[
\begin{bmatrix}
    \MyTikzmark{leftA}{15} &  0 &  \MyTikzmark{topB}{0} &  \MyTikzmark{rightA}{0} \\
     0 & 50 & 20 & 25 \\
    35 &  5 &  0 & 10 \\
    \MyTikzmark{bottomA}{0} & 65 & \MyTikzmark{bottomB}{50} & 65
\end{bmatrix}
\]
\DrawVLine[red, thick, opacity=0.5]{leftA}{bottomA}
\DrawVLine[orange, thick, opacity=0.5]{topB}{bottomB}
\DrawHLine[blue, thick, opacity=0.5]{leftA}{rightA}
\end{document}

Code: With tikzmark package.

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{calc,tikzmark}

\newcommand{\MyTikzmark}[2]{%
    \tikz[remember picture,baseline] 
        \node [anchor=base, inner sep=0pt, outer sep=0pt] 
            {\tikzmark{#1 LEFT}$#2$\tikzmark{#1 RIGHT}};%
 }

\newcommand{\DrawVLine}[3][]{%
  \begin{tikzpicture}[overlay,remember picture]
    \draw[shorten <=-1.7ex, shorten >=-0.3ex, #1] 
            ($(pic cs:#2 LEFT)!0.5!(pic cs:#2 RIGHT)$) -- 
            ($(pic cs:#3 LEFT)!0.5!(pic cs:#3 RIGHT)$);
  \end{tikzpicture}
}

\newcommand{\DrawHLine}[3][]{%
  \begin{tikzpicture}[overlay,remember picture]
    \draw[shorten <=-0.2em, shorten >=-0.3em, yshift=0.7ex, #1] 
            (pic cs:#2 LEFT) --  (pic cs:#3 RIGHT);
  \end{tikzpicture}
}


\begin{document}
\[
\begin{bmatrix}
    \MyTikzmark{leftA}{15} &  0 &  \MyTikzmark{topB}{0} &  \MyTikzmark{rightA}{0} \\
     0 & 50 & 20 & 25 \\
    35 &  5 &  0 & 10 \\
    \MyTikzmark{bottomA}{0} & 65 & \MyTikzmark{bottomB}{50} & 65
\end{bmatrix}
\]
\DrawVLine[red,   thick, opacity=0.5]{leftA}{bottomA}
\DrawVLine[orange,thick, opacity=0.5]{topB}{bottomB}
\DrawHLine[blue,  thick, opacity=0.5]{leftA}{rightA}
\end{document}
2
  • Could you update the answer taking into account that now there is a library for \tikzmark?
    – egreg
    Commented Mar 28, 2015 at 19:03
  • @egreg: Added a tikzmark package version, but for this case I think it is easier to not use the package. See "Notes" section. Apologies for the delay in responding. Commented Apr 6, 2015 at 2:30
6

No real need for TikZ here, although I would not pretend this solution is very robust.

\documentclass{article}
\begin{document}
$$\left[\begin{array}{cccc}
\smash{\vrule width .5pt depth 42pt height 4pt}&&
\smash{\vrule width .5pt depth 42pt height 4pt}\\[-8pt]
\hbox to 0pt{\vrule width 1in depth -3pt height 3.5pt\hss}
15&0&0&0\\
0&50&20&25\\
35&5&0&10\\
0&65&50&65
\end{array}\right]$$
\end{document}

enter image description here

4

Without tikzmark or matrix of nodes , a simple solution is to use the \rule command with proper adjustment of lift, width, and length. Here is how to implement this:

\documentclass{article} 
\usepackage{amsmath}
\begin{document}
\[\begin{bmatrix}
  15\makebox(-10,0){\rule[-18.5ex]{0.4pt}{4\normalbaselineskip}} 
     & 0 & 0 \makebox(-5,0){\rule[-18.5ex]{0.4pt}{4\normalbaselineskip}} 
             \makebox(-25,0){\rule[1.5ex]{6\normalbaselineskip}{0.4pt}} 
               & 0 \\
  0  & 50 & 20 & 25 \\
  35 & 5  & 0  & 10 \\
  0  & 65 & 50 & 65
\end{bmatrix}\]
\end{document}

The output as required:

enter image description here

3

I would do this differently using a matrix of math nodes:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}

\begin{document}

\begin{center}
  \begin{tikzpicture}
    \matrix (M)[matrix of math nodes,left delimiter={[},right delimiter={]}]{
      15 & 0 & 0 & 0\\
      0 & 50 & 20 & 25 \\
      35 & 5 & 0 & 10\\
      0 & 65 & 50 & 65\\
     };
     \draw[thick,black](M-1-1.west)--(M-1-4.east);
     \draw[thick,black](M-1-1.north)--(M-4-1.south);
     \draw[thick,black](M-1-3.north)--(M-4-3.south);
  \end{tikzpicture}
\end{center}

\end{document}

The (M) argument to \matrix means that you can refer to the nodes as (M-row-col).

Note that you need to escape the delimiters as {[} and {]}. This gives:

enter image description here

1

I thought I'd have a go at it too. I tried to compute as much as possible, but still need fudge factors to vertically center the lines over the numbers. At least it should be independent of font size.

\documentclass{article}
\usepackage{mathtools}

\newsavebox{\tempbox}
\newlength{\tempwidth}
\newlength{\tempheight}

% drwa horizontal line across matrix
\newcommand{\hmline}{\rlap{\rule[.6ex]{\tempwidth}{.5ex}}}

% draw vertical line up from bottom row of matrix
\newcommand{\vmline}[1]% #1 = comun entry (bottom row)
{\begingroup%
\settowidth{\tempwidth}{$#1$}%
\addtolength{\tempwidth}{-.5ex}% line width
\rlap{\hspace{.5\tempwidth}\raisebox{-.8ex}[0pt][0pt]{\rule{.5ex}{\tempheight}}}#1%
\endgroup}

\begin{document}
% compute size of matrix (no brackets}
\savebox{\tempbox}{$\displaystyle\begin{matrix}
    15 &  0 &  0 &  0 \\
     0 & 50 & 20 & 25 \\
    35 &  5 &  0 & 10 \\
     0 & 65 & 50 & 65
\end{matrix}$}%
\settoheight{\tempheight}{\usebox{\tempbox}}%
\settodepth{\tempwidth}{\usebox{\tempbox}}%
\addtolength{\tempheight}{\tempwidth}%
\settowidth{\tempwidth}{\usebox{\tempbox}}%

\[
\begin{bmatrix}
    \hmline
    15 &  0 &  0 &  0 \\
     0 & 50 & 20 & 25 \\
    35 &  5 &  0 & 10 \\
    \vmline{0} & 65 & \vmline{50} & 65
\end{bmatrix}
\]
\end{document}

matrix

You must log in to answer this question.

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