# Enhancing heatmap of triangular/sparse matrix

This is a follow-up question to: Heatmap of a triangular matrix (or a sparse matrix) (where also the code is taken from)

What I want to achieve (Excel draft):

What I got so far (see code at bottom):

What is missing:

• Axis description with "Some Text"
• Removing the "xxx" hack to get the first column being recognized as strings

Possible solution for removing the "xxx" hack: I found that "automatic column numbering" was done here: Diverging color scale for a table heatmap and my dream solution would be not only incorporating it to my heatmap but also extending it with "automatic row numbering".

Current Code:

\documentclass{standalone}
\usepackage{colortbl}
\usepackage{pgfplots}
\usepackage{pgfplotstable}

\pgfplotstableset{
/color cells/min/.initial=0,
/color cells/max/.initial=1000,
/color cells/textcolor/.initial=,
%
% Usage: 'color cells={min=<value which is mapped to lowest color>,
%   max = <value which is mapped to largest>}
color cells/.code={%
\pgfqkeys{/color cells}{#1}%
\pgfkeysalso{%
postproc cell content/.code={%
%
\begingroup
%
% acquire the value before any number printer changed
% it:
\pgfkeysgetvalue{/pgfplots/table/@preprocessed cell content}\value
\ifx\value\empty
\endgroup
\else
\pgfmathfloatparsenumber{\value}%
\pgfmathfloattofixed{\pgfmathresult}%
\let\value=\pgfmathresult
%
% map that value:
\pgfplotscolormapaccess
[\pgfkeysvalueof{/color cells/min}:\pgfkeysvalueof{/color cells/max}]%
{\value}%
{\pgfkeysvalueof{/pgfplots/colormap name}}%
% now, \pgfmathresult contains {<R>,<G>,<B>}
%
% acquire the value AFTER any preprocessor or
% typesetter (like number printer) worked on it:
\pgfkeysgetvalue{/pgfplots/table/@cell content}\typesetvalue
\pgfkeysgetvalue{/color cells/textcolor}\textcolorvalue
%
% tex-expansion control
% see http://tex.stackexchange.com/questions/12668/where-do-i-start-latex-programming/27589#27589
\toks0=\expandafter{\typesetvalue}%
\xdef\temp{%
\noexpand\pgfkeysalso{%
@cell content={%
\noexpand\cellcolor[rgb]{\pgfmathresult}%
\noexpand\definecolor{mapped color}{rgb}{\pgfmathresult}%
\ifx\textcolorvalue\empty
\else
\noexpand\color{\textcolorvalue}%
\fi
\the\toks0 %
}%
}%
}%
\endgroup
\temp
\fi
}%
}%
}
}

\begin{document}

\vrule\pgfplotstabletypeset[%
color cells={min=365,max=375,textcolor=black},
/pgfplots/colormap={orangewhiteorange}{rgb255=(255,170,0) color=(white) rgb255=(255,170,0)},
/pgf/number format/fixed,
/pgf/number format/precision=0,
col sep=comma,
columns/xxx/.style={reset styles,string type}%
]{%%%%%%%
xxx, 0, 1, 2, 3, 4, 5, 6
0, 370.8, 371.2, 371.1, 370.9, 371.2, 371.6, 372.0
1, 370.4, 370.3, 370.4, 370.7, 370.8, 371.4, 371.5
2, 370.9, , 370.7, 370.9, 370.8, 371.2, 372.1
3, 371.0, , , 368.1, 371.1, 368.8, 371.3
4, 370.9, , , , 371.1, 371.4, 371.4
5, 371.7, , , , , 371.1, 371.4
6, 372.0, , , , , , 371.2
}\vrule
\end{document}


Any help is appreciated!

Here is a way to do this by extending my code from How to interpolate two colors in a cell? to produce:

Here is the code:

  \documentclass{article}
\usepackage[table,x11names]{xcolor}
\usepackage{collcell}
\usepackage{array}
\usepackage{tikz}
\usepackage{pgfkeys}
\usepackage{graphicx}

% set up pgfkeys for controlling heat specifications
\pgfkeys{/heat/.is family, /heat,
Max colour/.initial = Green4,
Min colour/.initial = Red1,
max colour/.initial = SpringGreen3,
min colour/.initial = Yellow1,
text colour/.initial = black,
Min color/.style = {Min colour=#1},% for our friends who can't spell
Max color/.style = {Max colour=#1},
min color/.style = {min colour=#1},
max color/.style = {max colour=#1},
text color/.style = {text colour=#1},
min/.initial = -1,
max/.initial = 1,
slider/.code={%
right color=\HVal{max colour}]%
(current page.south west) rectangle ++(#1,12pt);
}%
}%
}
\newcommand\Heatset[1]{\pgfkeys{/heat, #1}}
\newcommand\HVal[1]{\pgfkeysvalueof{/heat/#1}}

\newcolumntype{H}{>{\collectcell\Heat}r<{\endcollectcell}}
\newcommand\Heat[1]{% \Heat{number in the interval [min, max] }
\if\relax\detokenize{#1}\relax% empty cell
\else%
\pgfmathparse{int(100*(#1-\HVal{min})/(\HVal{max}-\HVal{min}))}% map number to [0,100]
\ifnum\pgfmathresult>100% too big
\edef\HeatCell{\noexpand\cellcolor{\HVal{Max colour}}}%
\else\ifnum\pgfmathresult<0% too small
\edef\HeatCell{\noexpand\cellcolor{\HVal{Min colour}}}%
\else% between min and max
\edef\HeatCell{\noexpand\cellcolor{\HVal{max colour}!\pgfmathresult!\HVal{min colour}}}%
\fi%
\fi%
\HeatCell\textcolor{\HVal{text colour}}{$#1$}%
\fi%
}

\begin{document}

\Heatset{min=370,   % maximum value
max=372,   % minimum value
max colour=Burlywood2, % colour at maximum
min colour=Snow1,      % colour at minimum
Min colour=OrangeRed1, % colour for values below min
Max colour=SeaGreen3   % colour for values above max
}

\begin{tabular}{ cc *7H }
&  \multicolumn8c{\textsf{Some text}}\\
& &\multicolumn1c{0}&\multicolumn1c{1}&\multicolumn1c{2}&\multicolumn1c{3}
&\multicolumn1c{4}&\multicolumn1c{5}&\multicolumn1c{6}\\
& 0& 370.8& 371.2& 371.1& 370.9& 371.2& 371.6& 372.0\\
& 1& 370.4& 370.3& 370.4& 370.7& 370.8& 371.4& 371.5\\
& 2& 370.9& & 370.7& 370.9& 370.8& 371.2& 372.1\\
\rotatebox{90}{\makebox[0pt]{\textsf{Some text}}}
& 3& 371.0& & & 368.1& 371.1& 368.8& 371.3\\
& 4& 370.9& & & & 371.1& 371.4& 371.4\\
& 5& 371.7& & & & & 371.1& 371.4\\
& 6& 372.0& & & & & & 371.2\\
\end{tabular}

\end{document}


• In the code from How to interpolate two colors in a cell?, the colours etc can be set using the \Heatset command. The relevant lines in the MWE are:

\Heatset{min=370,   % maximum value
max=372,   % minimum value
max colour=Burlywood2, % colour at maximum
min colour=Snow1,      % colour at minimum
Min colour=OrangeRed1, % colour for values below min
Max colour=SeaGreen3   % colour for values above max
}

• The text along the top is easy: just put it inside a \multicolumn

• The side at the side is slightly trickier. The \rotatebox command from the graphicx package lets you rotate text but if you do this naively then the fourth row of the table with have the same height as some text. To get around this I have used \makebox to put the text in a box of width zero.
• The code \if\relax\detokenize{#1}\relax is a standard way to test if #1 is empty
• If the number is above max or below min then the corresponding Max/Min colour is printed...there's no shading here