Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like to draw frameworks around certain submatrices of a large matrix, like described in this question: Highlight elements in the matrix.

I tried some of the provided solutions and ended up using this one:

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\usepackage{color}
\definecolor{orange}{RGB}{255,127,0}
\usetikzlibrary{arrows,matrix,positioning}
\usepackage{xfrac}
\begin{document}

\begin{tikzpicture}
\matrix [matrix of math nodes,left delimiter=(,right delimiter=)] (m)
{
1 & 0 & 0 & 0 & 0 & 0 & 0\\ 
0 & 1 & 0 & 0 & 0 & 0 & 0\\ 
0 & \frac{1}{2} & \frac{1}{2} & 0 & 0 & 0 & 0\\ 
0 & \frac{1}{4} & \frac{7}{12} & \frac{1}{6} & 0 & 0 & 0\\ 
0 & 0 & \frac{2}{3} & \frac{1}{3} & 0 & 0 & 0\\ 
0 & 0 & \frac{1}{3} & \frac{2}{3} & 0 & 0 & 0\\ 
0 & 0 & \frac{1}{6} & \frac{2}{3} & \frac{1}{6} & 0 & 0\\ 
0 & 0 & 0 & \frac{2}{3} & \frac{1}{3} & 0 & 0\\ 
0 & 0 & 0 & \frac{1}{3} & \frac{2}{3} & 0 & 0\\ 
0 & 0 & 0 & \frac{1}{6} & \frac{7}{12} & \frac{1}{4} & 0\\ 
0 & 0 & 0 & 0 & \frac{1}{2} & \frac{1}{2} & 0\\ 
0 & 0 & 0 & 0 & 0 & 1 & 0\\ 
0 & 0 & 0 & 0 & 0 & 0 & 1\\
};  
\draw[color=orange,line width=1pt] (m-1-1.north west) -- (m-1-4.north east) -- (m-4-4.south east) -- (m-4-1.south west) -- cycle;
\draw[color=orange,line width=1pt] (m-4-2.north west) -- (m-4-5.north east) -- (m-7-5.south east) -- (m-7-2.south west) -- cycle;
\draw[color=orange,line width=1pt] (m-7-3.north west) -- (m-7-6.north east) -- (m-10-6.south east) -- (m-10-3.south west) -- cycle;
\draw[color=orange,line width=1pt] (m-10-4.north west) -- (m-10-7.north east) -- (m-13-7.south east) -- (m-13-4.south west) -- cycle;
\end{tikzpicture}            

\end{document}

The thing is, when in a certain row there are both plain numbers and fractions, the frameworks are skewed like this:

enter image description here

How can I fix this? I tried to replace each \frac by \sfrac (that's why I added the package xfrac), but this makes the problem even worse.

share|improve this question
1  
have a look at my answer to problems-using-left-in-array-environment/52714#52714 –  cmhughes May 1 '12 at 12:10
    
@cmhughes, that's a very nice solution indeed. However, I'd like to use the construction from my post (so drawing the frameworks afterwards) in order to automate this process. –  Ailurus May 1 '12 at 12:16
    
Also if you are typing lots of sparse matrices as I do, please have a look at this answer –  percusse May 1 '12 at 12:22
    
Hmm, I just noticed a new answer (for some reason it's gone now), providing the following solution. Add nodes={text depth=0.4ex, text height=1.6ex} to the matrix. This works fine for normal fractions, but doesn't solve the problem when using \sfrac (which wasn't very clearly indicated in my question, I know). –  Ailurus May 1 '12 at 12:24
    
@percusse, thanks for the suggestion. Since that question was actually posted by me, I already knew it ;) –  Ailurus May 1 '12 at 12:37

3 Answers 3

up vote 10 down vote accepted

With fit. (update) I added a new style rec.

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\usepackage{color}
\definecolor{orange}{RGB}{255,127,0}
\usetikzlibrary{arrows,matrix,positioning,fit}
\usepackage{xfrac}
\begin{document}

\begin{tikzpicture}[rec/.style={draw=orange,thick,inner sep=0}]
\matrix [matrix of math nodes,left delimiter=(,right delimiter=)] (m)
{
  1 & 0 & 0 & 0 & 0 & 0 & 0\\ 
  0 & 1 & 0 & 0 & 0 & 0 & 0\\ 
  0 & \sfrac{1}{2} & \sfrac{1}{2} & 0 & 0 & 0 & 0\\ 
  0 & \sfrac{1}{4} & \sfrac{7}{12} & \sfrac{1}{6} & 0 & 0 & 0\\ 
  0 & 0 & \sfrac{2}{3} & \sfrac{1}{3} & 0 & 0 & 0\\ 
  0 & 0 & \sfrac{1}{3} & \sfrac{2}{3} & 0 & 0 & 0\\ 
  0 & 0 & \sfrac{1}{6} & \sfrac{2}{3} & \sfrac{1}{6} & 0 & 0\\ 
  0 & 0 & 0 & \sfrac{2}{3} & \sfrac{1}{3} & 0 & 0\\ 
  0 & 0 & 0 & \sfrac{1}{3} & \sfrac{2}{3} & 0 & 0\\ 
  0 & 0 & 0 & \sfrac{1}{6} & \sfrac{7}{12} & \sfrac{1}{4} & 0\\ 
  0 & 0 & 0 & 0 & \sfrac{1}{2} & \sfrac{1}{2} & 0\\ 
  0 & 0 & 0 & 0 & 0 & 1 & 0\\ 
  0 & 0 & 0 & 0 & 0 & 0 & 1\\
};  
\node[fit=(m-1-1)(m-4-4),  rec] {}; 
\node[fit=(m-4-2)(m-7-5),  rec] {};  
\node[fit=(m-7-3)(m-10-6), rec] {};  
\node[fit=(m-10-4)(m-13-7),rec] {};  
\end{tikzpicture}            

\end{document}

enter image description here

share|improve this answer
    
Very nice, TikZ is just so elegant! I think I'll spend some time reading the manual and studying a few more examples. Thanks! –  Ailurus May 1 '12 at 12:21
    
I think I would list all four corner nodes in the fit just to be on the safe side. If the off-corners are bigger than the on-corners, listing only two might not look well with the off-corners. –  Loop Space May 1 '12 at 12:27
    
Hmm, is it possible to shrink the frameworks a little? Because right now, they overlap part of the fractions. –  Ailurus May 1 '12 at 12:27
    
Yes with inner sep=0 in the new nodes –  Alain Matthes May 1 '12 at 12:36
    
See, I really need some time to thoroughly read the TikZ manual. Thanks again, marked as accepted answer. –  Ailurus May 1 '12 at 12:38

The two answers provided have some limitation. illustrated in the following variation of the MWE:

\documentclass[tikz]{standalone}
%\url{http://tex.stackexchange.com/q/53938/86}
\usepackage{amsmath}
\usepackage{matrixcells}
\usetikzlibrary{matrix, fit}
\usepackage{xfrac}
\begin{document}

\begin{tikzpicture}
\matrix [matrix of math nodes,left delimiter=(,right delimiter=),label cells, nodes={anchor=north}] (m)
{
1 & 0 & 0 & 0 & 0 & 0 & 0\\
0 & 1 & 0 & 0 & 0 & 0 & 0\\
0 & \frac{1}{2} & \frac{1}{2} & 0 & 0 & 0 & 0\\
0 & \frac{1}{4} & \frac{7}{12} & \frac{1}{6} & 0 & 0 & 0\\
1000000 & 0 & \frac{2}{3} & \frac{1}{3} & 0 & 0 & 0\\
0 & 0 & \frac{1}{3} & \frac{2}{3} & 0 & 0 & 0\\
0 & 0 & \frac{1}{6} & \frac{2}{3} & \frac{1}{6} & 0 & 0\\
0 & 0 & 0 & \frac{2}{3} & \frac{1}{3} & 0 & 0\\
0 & 0 & 0 & \frac{1}{3} & \frac{2}{3} & 0 & 0\\
0 & 0 & 0 & \frac{1}{6} & \frac{7}{12} & \frac{1}{4} & 0\\
0 & 0 & 0 & 0 & \frac{1}{2} & \frac{1}{2} & 0\\
0 & 0 & 0 & 0 & 0 & 1 & 0\\
0 & 0 & 0 & 0 & 0 & 0 & 1\\
};
\draw[color=orange,line width=1pt] (m-cell-1-1.north west) -- (m-cell-1-4.north east) -- (m-cell-4-4.south east) -- (m-cell-4-1.south west) -- cycle;
\draw[color=orange,line width=1pt] (m-cell-4-2.north west) -- (m-cell-4-5.north east) -- (m-cell-7-5.south east) -- (m-cell-7-2.south west) -- cycle;
\draw[color=orange,line width=1pt] (m-cell-7-3.north west) -- (m-cell-7-6.north east) -- (m-cell-10-6.south east) -- (m-cell-10-3.south west) -- cycle;
\draw[color=orange,line width=1pt] (m-cell-10-4.north west) -- (m-cell-10-7.north east) -- (m-cell-13-7.south east) -- (m-cell-13-4.south west) -- cycle;

\node[draw=green, fit=(m-1-1)(m-4-4)] {};
\node[draw=green, fit=(m-4-2)(m-7-5)] {};
\node[draw=green, fit=(m-7-3)(m-10-6)] {};
\node[draw=green, fit=(m-10-4)(m-13-7)] {};
\end{tikzpicture}

\end{document}

output

The green boxes correspond to @AlainMatthes 's answer and the orange to @AndrewStacey 's answer.

The orange contours are off due to the change of anchor (full explanation in this answer).

The green contours are off because the dimension of the contour cannot be determined only by the nodes it contain. This is an extension of @AndrewStacey 's comment about which nodes to include in the fit.

As mentioned in this same answer, I have fixed the anchor problem in matrixcells in matrix.skeleton. The following example shows the proper contours in orange:

\documentclass[tikz]{standalone}
%\url{http://tex.stackexchange.com/q/53938/86}
\usepackage{amsmath}
\usetikzlibrary{matrix.skeleton}
\usepackage{xfrac}
\begin{document}

\begin{tikzpicture}
\matrix [matrix of math nodes,left delimiter=(,right delimiter=),label skeleton, nodes={anchor=north}] (m)
{
1 & 0 & 0 & 0 & 0 & 0 & 0\\
0 & 1 & 0 & 0 & 0 & 0 & 0\\
0 & \frac{1}{2} & \frac{1}{2} & 0 & 0 & 0 & 0\\
0 & \frac{1}{4} & \frac{7}{12} & \frac{1}{6} & 0 & 0 & 0\\
1000000 & 0 & \frac{2}{3} & \frac{1}{3} & 0 & 0 & 0\\
0 & 0 & \frac{1}{3} & \frac{2}{3} & 0 & 0 & 0\\
0 & 0 & \frac{1}{6} & \frac{2}{3} & \frac{1}{6} & 0 & 0\\
0 & 0 & 0 & \frac{2}{3} & \frac{1}{3} & 0 & 0\\
0 & 0 & 0 & \frac{1}{3} & \frac{2}{3} & 0 & 0\\
0 & 0 & 0 & \frac{1}{6} & \frac{7}{12} & \frac{1}{4} & 0\\
0 & 0 & 0 & 0 & \frac{1}{2} & \frac{1}{2} & 0\\
0 & 0 & 0 & 0 & 0 & 1 & 0\\
0 & 0 & 0 & 0 & 0 & 0 & 1\\
};

\node[draw=orange, fit=(m-cell-1-1)(m-cell-4-4)] {};
\node[draw=orange, fit=(m-cell-4-2)(m-cell-7-5)] {};
\node[draw=orange, fit=(m-cell-7-3)(m-cell-10-6)] {};
\node[draw=orange, fit=(m-cell-10-4)(m-cell-13-7)] {};

\node[draw=green, fit=(m-1-1)(m-4-4)] {};
\node[draw=green, fit=(m-4-2)(m-7-5)] {};
\node[draw=green, fit=(m-7-3)(m-10-6)] {};
\node[draw=green, fit=(m-10-4)(m-13-7)] {};
\end{tikzpicture}

\end{document}

correct output

share|improve this answer

The beta package matrixcells eats this sort of thing for breakfast. Here's your code with a modicum of changes - I'm tempted to set this as a "spot the difference" between the original code and this.

\documentclass{article}
%\url{http://tex.stackexchange.com/q/53938/86}
\usepackage{amsmath}
\usepackage{tikz}
\usepackage{matrixcells}
\usepackage{color}
\definecolor{orange}{RGB}{255,127,0}
\usetikzlibrary{arrows,matrix,positioning}
\usepackage{xfrac}
\begin{document}

\begin{tikzpicture}
\matrix [matrix of math nodes,left delimiter=(,right delimiter=),label cells] (m)
{
1 & 0 & 0 & 0 & 0 & 0 & 0\\ 
0 & 1 & 0 & 0 & 0 & 0 & 0\\ 
0 & \frac{1}{2} & \frac{1}{2} & 0 & 0 & 0 & 0\\ 
0 & \frac{1}{4} & \frac{7}{12} & \frac{1}{6} & 0 & 0 & 0\\ 
0 & 0 & \frac{2}{3} & \frac{1}{3} & 0 & 0 & 0\\ 
0 & 0 & \frac{1}{3} & \frac{2}{3} & 0 & 0 & 0\\ 
0 & 0 & \frac{1}{6} & \frac{2}{3} & \frac{1}{6} & 0 & 0\\ 
0 & 0 & 0 & \frac{2}{3} & \frac{1}{3} & 0 & 0\\ 
0 & 0 & 0 & \frac{1}{3} & \frac{2}{3} & 0 & 0\\ 
0 & 0 & 0 & \frac{1}{6} & \frac{7}{12} & \frac{1}{4} & 0\\ 
0 & 0 & 0 & 0 & \frac{1}{2} & \frac{1}{2} & 0\\ 
0 & 0 & 0 & 0 & 0 & 1 & 0\\ 
0 & 0 & 0 & 0 & 0 & 0 & 1\\
};  
\draw[color=orange,line width=1pt] (m-cell-1-1.north west) -- (m-cell-1-4.north east) -- (m-cell-4-4.south east) -- (m-cell-4-1.south west) -- cycle;
\draw[color=orange,line width=1pt] (m-cell-4-2.north west) -- (m-cell-4-5.north east) -- (m-cell-7-5.south east) -- (m-cell-7-2.south west) -- cycle;
\draw[color=orange,line width=1pt] (m-cell-7-3.north west) -- (m-cell-7-6.north east) -- (m-cell-10-6.south east) -- (m-cell-10-3.south west) -- cycle;
\draw[color=orange,line width=1pt] (m-cell-10-4.north west) -- (m-cell-10-7.north east) -- (m-cell-13-7.south east) -- (m-cell-13-4.south west) -- cycle;
\end{tikzpicture}            

\end{document}

Here's the result:

Matrix with cells outlined

The matrixcells package puts rectangular nodes over each of the cells of a TikZ matrix in such a way that they tile the matrix. This ensures that their edges line up and so forth. Thus they are better designed for outlining regions of a matrix than the individual cells themselves. For example, if one of the non-corner nodes happens to be extra tall then Altermundus' code won't adapt to this whereas the above will. Here's the comparison with Altermundus' code producing the orange lines and mine producing the green.

Comparison of methods

share|improve this answer
    
you are right but the mixt of different styles of fractions are not very elegant. But in this case, you have several options but \node[fit=(m-4-2)(m-4-3)(m-7-5), rec] {}; is efficient . –  Alain Matthes May 1 '12 at 19:01
    
@Altermundus Of course it's not elegant - it was a quite hack to demonstrate the issue. And you can, as you point out, add the tallest node to the fit to make that work. But this method works automatically. It's an alternative, that's all. –  Loop Space May 1 '12 at 19:24
    
@AndrewStacey, thanks for this alternative solution! –  Ailurus May 1 '12 at 21:05

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.