11

So let me first of all shamelessly steal heatmap code from this answer to Drawing heatmaps using TikZ

\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
                \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 https://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
            }%
        }%
    }
}

\begin{document}
\pgfplotstabletypeset[
     color cells={min=-1,max=1,textcolor=black},
     /pgfplots/colormap={orangewhiteorange}{rgb255=(255,170,0) color=(white) rgb255=(255,170,0)},
    /pgf/number format/fixed,
    /pgf/number format/precision=3,
    col sep=comma,
    columns/Correlations/.style={reset styles,string type}
]{
Correlations,a,b,c,d
a,1,,,
b,0.448,1,,
c,-0.295,-0.136,1,
d,-0.350,-0.154,0.313,1
}
\end{document}

This would work just fine, if only there weren't those empty cells which produce nasty errors because they can't be parsed as a floating point number.

I tried to blindly fiddle around with stuff like \ifx\value\empty\let\value=0\fi but I only managed to produce different errors.

What this is supposed to look is this table (just more regular and with better alignment): heatmap of triangular matrix

Christian
  • 19,238

1 Answers1

9

You can check for empty and skip all the code that causes problems. enter image description here

\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}


aaa\vrule\pgfplotstabletypeset[%
     color cells={min=-1,max=1,textcolor=black},
     /pgfplots/colormap={orangewhiteorange}{rgb255=(255,170,0) color=(white) rgb255=(255,170,0)},
    /pgf/number format/fixed,
    /pgf/number format/precision=3,
    col sep=comma,
    columns/Correlations/.style={reset styles,string type}%
]{%%%%%%%
Correlations,a,b,c,d
a,1,,,
b,0.448,1,,
c,-0.295,-0.136,1,
d,-0.350,-0.154,0.313,1
}\vrule bbb
\end{document}
David Carlisle
  • 757,742
  • BTW, your little uncropped picture shows it nicely: any idea why the code of this particular MWE produces so much white space on the left? It happens to a lesser extent in my actual code, too, so the whole table is set too far to the right which makes alignment a pain obviously. – Christian Feb 02 '13 at 02:03
  • @Christian I couldn't find the extra space source but \begingroup\nullfont removes most of it (which is another clue that there is a spurious space somewhere in the code). Also it's the first object so \noindent also removes some of it. However it's still not completely removed. – percusse Feb 02 '13 at 02:30
  • some of it are missing % at ends of lines I don't really read tikz but adding a few % reduced the space, still more than it ought to be probably. I'll update the code and image – David Carlisle Feb 02 '13 at 02:32
  • I'm sorry for putting just another question in the comments. Probably I should open a new question for this. I thought adding some alignment stuff would be easy but I can't get something like columns/a/.style={minimum width = 10em, column type={S[table-format=-1.3]}} to work :/ Any quick ideas? Otherwise I can really make this into a new question. – Christian Feb 02 '13 at 11:59
  • I have never used tikz. (But I can wrap tikz code in \ifx...\fi to stop it executing:-) – David Carlisle Feb 02 '13 at 12:01
  • @Christian the key minimum width is used for TikZ nodes only. And your approach does not use TikZ at all - it is just a plain tabular environment. Perhaps a column type of p{10em} would be what you need? – Christian Feuersänger Feb 02 '13 at 19:42
  • @ChristianFeuersänger Yes, working only with column types (and self-defined at that) does what I need. Thanks! – Christian Feb 04 '13 at 14:57
  • how can I use two heatmap in the same table? – leonardo cesar Jul 30 '14 at 12:57
  • @leonardocesar sorry not sure I understand the comment, but anyway it is best to ask new questions as a new question rather than as comments in an old one. (I know nothing at all about tikz:-) – David Carlisle Jul 30 '14 at 13:15