I would like to write a matrix equation, where the matrix contains equally sized coloured blocks on the diagonal.
Something like:
Does anyone have any idea how to go about this?
matrices
I would like to write a matrix equation, where the matrix contains equally sized coloured blocks on the diagonal.
Something like:
Does anyone have any idea how to go about this?
Each block need its own pair of marks; I changed the definition of \tikzdrawbox
; the first mandatory argument is a number used for the marks; the second optional argument allows you to pass options to \draw
and the optional argument allows you to specify some "correction" to the block dimensions to prevent some borders to overlap:
\documentclass{article}
\usepackage{pgf}
\usepackage{tikz}
\usetikzlibrary{calc,fit,matrix,arrows,automata,positioning}
\newcommand\x{\times}
\newcommand\y{\colorbox{red}{$\times$}}
\newcommand\z{\colorbox{gray}{$\times$}}
\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}
\newcommand{\tikzdrawbox}[3][(0pt,0pt)]{%
\tikz[overlay,remember picture]{
\draw[#3]
($(left#2)+(-0.3em,0.9em) + #1$) rectangle
($(right#2)+(0.2em,-0.4em) - #1$);}
}
\begin{document}
\begin{equation}\label{eq:blockedgivens}
\left(\begin{array}{ccccccccccccccc}
\x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
0 & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
0 & 0 & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
0 & 0 & 0 & \tikzmark{left1}\x & \x & \x & \x & \tikzmark{left3}\x & \x & \x & \x & \x & \x & \x & \x \\
0 & 0 & 0 & \z & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
0 & 0 & 0 & 0 & \z & \x & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
0 & 0 & 0 & 0 & 0 & \z & \x & \x & \x & \x & \x & \x & \x & \x & \x \\
0 & 0 & 0 & 0 & 0 & 0 & \z & \tikzmark{left2} \x \tikzmark{right1} & \x & \x & \x & \tikzmark{left4} \x & \x & \x & \x \tikzmark{right3} \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & \z & \x & \x & \x & \x & \x & \x & \x \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \z & \x & \x & \x & \x & \x & \x \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \z & \x & \x & \x & \x & \x \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \z & \x \tikzmark{right2} & \x & \x & \x \tikzmark{right4} \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \z & \x & \x & \x \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \z & \x & \x \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \z & \x \\
\end{array}\right)
\tikzdrawbox{1}{thick,red}
\tikzdrawbox{2}{thick,red}
\tikzdrawbox[(-1pt,2pt)]{3}{thick,green}
\tikzdrawbox[(-4pt,2pt)]{4}{thick,green}
\end{equation}
\end{document}
The answer provides two solutions: by means of the first one it is possible to customize the dimension of the squares and perhaps suits better your needs. Both are based on answers given here.
Solution n.1 is based on Create square and custom size cells in a table using pgfplotstable:
\documentclass{article}
\usepackage{filecontents}
\usepackage[table]{xcolor}
\usepackage{pgfplotstable}
\usetikzlibrary{calc}
\pgfplotsset{compat=1.8}
\begin{filecontents}{matrix.cvs}
1 0 1 1 0 1 0 1 0 1 0
1 0 0 1 0 1 0 1 0 1 0
0 1 0 1 0 1 1 1 0 1 0
1 1 1 1 0 0 1 0 1 0 0
0 1 1 0 0 0 1 1 0 0 1
1 1 1 0 1 0 1 0 1 1 1
1 0 1 0 1 0 1 0 1 1 1
\end{filecontents}
\makeatletter
\tikzset{
zero color/.initial=white,
zero color/.get=\zerocol,
zero color/.store in=\zerocol,
one color/.initial=red,
one color/.get=\onecol,
one color/.store in=\onecol,
cell wd/.initial=1ex,
cell wd/.get=\cellwd,
cell wd/.store in=\cellwd,
cell ht/.initial=1ex,
cell ht/.get=\cellht,
cell ht/.store in=\cellht,
}
\newcommand{\drawgrid}[2][]{
\medskip
\begin{tikzpicture}[#1]
\pgfplotstableforeachcolumn#2\as\col{
\pgfplotstableforeachcolumnelement{\col}\of#2\as\colcnt{%
\ifnum\colcnt=0
\fill[\zerocol]($ -\pgfplotstablerow*(0,\cellht) + \col*(\cellwd,0) $) rectangle+(\cellwd,\cellht);
\fi
\ifnum\colcnt=1
\fill[\onecol]($ -\pgfplotstablerow*(0,\cellht) + \col*(\cellwd,0) $) rectangle+(\cellwd,\cellht);
\fi
}
}
\end{tikzpicture}
\medskip
}
\makeatother
\begin{document}
% read the file
\pgfplotstableread{matrix.cvs}{\matrixfile}
\drawgrid{\matrixfile}
\drawgrid[zero color=green, one color=cyan]{\matrixfile}
\drawgrid[zero color=orange,
one color=violet,
cell ht=2em,
cell wd=2em]{\matrixfile}
\end{document}
The result:
Solution n.2 is based on Parametrize shading in table through TikZ:
\documentclass{article}
\usepackage{filecontents}
\usepackage[table]{xcolor}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.8}
\begin{filecontents}{matrix.cvs}
1 0 1 1 0 1 0 1 0 1 0
1 0 0 1 0 1 0 1 0 1 0
0 1 0 1 0 1 1 1 0 1 0
1 1 1 1 0 0 1 0 1 0 0
0 1 1 0 0 0 1 1 0 0 1
1 1 1 0 1 0 1 0 1 1 1
1 0 1 0 1 0 1 0 1 1 1
\end{filecontents}
\makeatletter
\pgfplotstableset{
zero color/.initial=white,
zero color/.get=\zerocol,
zero color/.store in=\zerocol,
one color/.initial=red,
one color/.get=\onecol,
one color/.store in=\onecol,
color cells/.style={
every head row/.style={output empty row},
string type,
postproc cell content/.code={%
\pgfkeysalso{@cell content=\rule{0cm}{2.4ex}\cellcolor{\zerocol}
\pgfmathtruncatemacro\number{##1}
\ifnum\number>0\cellcolor{\onecol}\fi}%
},
columns/x/.style={
column name={},
postproc cell content/.code={}
}
}
}
\makeatother
\begin{document}
% read the file
\pgfplotstableread{matrix.cvs}{\matrixfile}
\begin{table}
\centering
\pgfplotstabletypeset[color cells]\matrixfile
\end{table}
\begin{table}
\centering
\pgfplotstabletypeset[color cells, zero color=green, one color=cyan]\matrixfile
\end{table}
\end{document}
The result:
Best Answer
The following example calculates the contents of the matrix for the diagonal boxes automatically, given the number of rows. The environments for tables are a little tricky, because each cell is put in a group. Therefore the example first collects the contents of the matrix in a global macro
\DiagonalMatrixLines
and uses this macro inside the matrix environment. Macro\foreach
of packagepgffor
is used for the loop. (There are many other possibilities.)The square is determined by the height and depth of the row. The matrix environments are based on the environment
array
which inserts a special strut\@arstrut
to set a minimum height and depth of the row. The additioal white space added by environmentarray
is removed by setting\arraycolsep
to zero.\vdots
occupies a little more than one line, but it seems that the matrix with the diagonal boxes should not contain a row with\vdots
. Therefore is a matrix with four blocks smaller in height and with five blocks larger. The next example uses the inner part of the left matrix to get the height of the matrix and uses this height to resize the matrix with the diagonal blocks. The vertical middle of a matrix lies on the math axis.Therefore we must move the middle of the matrix to the baseline before resizing.