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 wanted to do some shading in a table according to its values. For example, if you see the table below:

  a  b   c   d 
a 90 10  0   0
b 0  80  10  10
c 0  0   95  5
d 0  10  5   85

I want to shade automatically each numeric cell with a mixture of black and white according to its value. That is, (a,a) = 90 should be something like black!90, and (c,d) = 5 should be black!5. Also, if you can parametrized the shading operation so one can define the color and if we use the value or the complement that would be great.

I was thinking in something like Drawing different tikz shapes parameterized by data from a file, but I cannot see how can one achieve that in a table.

Can you give me some advice on how to achieve such automatic styling?

share|improve this question
add comment

3 Answers 3

up vote 29 down vote accepted

You could use pgfplotstable and the xcolor package with the [table] option, which gives you the \cellcolor command.

Here's a new style for \pgfplotstabletypeset that colors the cell a different shade of gray according to the cell value, and prints the value in white if the background is more than 50% black.

The command

\pgfplotstabletypeset[color cells]{
 x,a,b,c,d      % The first column needs a name
 a,90,10,0,0
 b,0,80,10,10
 c,0,0,95,5
 d,0,10,5,85
 }

will then give you (shown here with a caption)

\documentclass{article}
\usepackage[table]{xcolor}
\usepackage{pgfplotstable}

\pgfplotstableset{
    color cells/.style={
        col sep=comma,
        string type,
        postproc cell content/.code={%
                \pgfkeysalso{@cell content=\rule{0cm}{2.4ex}\cellcolor{black!##1}\pgfmathtruncatemacro\number{##1}\ifnum\number>50\color{white}\fi##1}%
                },
        columns/x/.style={
            column name={},
            postproc cell content/.code={}
        }
    }
}

\begin{document}
\begin{table}\caption{Correlation or something}
\centering
\pgfplotstabletypeset[color cells]{
x,a,b,c,d
a,90,10.5,0,0
b,0,80,10,10
c,0,0,95,5
d,0,10,5,85
}
\end{table}
\end{document}
share|improve this answer
    
Thanks it works really nice. That was what I was expecting. However, when I put the \pgfplotstabletypeset inside a table environment (\begin{table} ... \end{table}) I get a Not in outer par mode error. So, is there any option to put that table in an environment? so I can add a caption to it, and style as other tables in my document? –  adn Jan 27 '12 at 6:25
    
That error occurs only if you're using the standalone class. In "normal" classes, you should be able to use the table environment. I've edited my example. –  Jake Jan 27 '12 at 6:35
    
Thanks, I feel so dumb. I didn't check that part. Now is working. By the way, is it me, or the numbers are not aligned in the middle of the rows? or is just a visual effect due to the shading? –  adn Jan 27 '12 at 6:43
1  
Don't worry, I was quite surprised that it didn't work in standalone, too. The numbers look like they're too far up because there's space left for the descender of letters like g, j, or q. If you add \rule{0cm}{2.4ex} before \cellcolor, they'll loke more centered. –  Jake Jan 27 '12 at 6:49
1  
\pgfmathtruncatemacro\somemacroname{##1}. You need to save the result into a macro, the command doesn't change the content of ##1 itself. –  Jake Jan 27 '12 at 6:59
show 2 more comments

I wanted to retain the use of tabular, so I used a macro to format the cells. Definitely longer but more familiar to me.

\def\cca#1{\cellcolor{black!#10}\ifnum #1>5\color{white}\fi{#1}}
%For ranges 0-10, multiply by 10 by adding 0 after #1

\begin{table}[!t]
\caption{Table Caption}
\label{tab1}
\centering
{\setlength\tabcolsep{0.1pt}%
\begin{tabular}{ccccccccccccccc}
& $D_1$ & $D_2$ & $D_3$ & $D_4$ & $D_5$ & $D_6$ && & $D_1$ & $D_2$ & $D_3$ & $D_4$ & $D_5$ & $D_6$ \\
$D_1$ & & \cca{0} & \cca{0} & \cca{0} & \cca{2} & \cca{0} && $D_1$ && \cca{0} & \cca{0} & \cca{2} & \cca{2} & \cca{2} \\
$D_2$ & \cca{0} & & \cca{2} & \cca{0} & \cca{2} & \cca{0} && $D_2$ & \cca{0} &  & \cca{3} & \cca{0} & \cca{0} & \cca{2} \\
$D_3$ & \cca{7} & \cca{4} &  & \cca{3} & \cca{0} & \cca{4} && $D_3$ & \cca{0} & \cca{4} &  & \cca{4} & \cca{2} & \cca{0} \\
$D_4$ & \cca{3} & \cca{0} & \cca{7} &  & \cca{4} & \cca{0} && $D_4$ & \cca{0} & \cca{0} & \cca{5} &  & \cca{0} & \cca{0} \\
$D_5$ & \cca{3} & \cca{7} & \cca{7} & \cca{2} &  & \cca{4} && $D_5$ & \cca{2} & \cca{2} & \cca{0} & \cca{4} &  & \cca{4} \\
$D_6$ & \cca{2} & \cca{2} & \cca{7} & \cca{2} & \cca{6} &  && $D_6$ & \cca{2} & \cca{2} & \cca{3} & \cca{0} & \cca{4} & \\
\end{tabular}}
\end{table}

table result

share|improve this answer
add comment
\definecolor{myFlowTableTextCol}{rgb}{0,0,0}
\definecolor{myFlowTableBgCol}{rgb}{1.0,0.5,0.0}

% Heatmap style
\pgfkeys{
/pgfplots/table/heatmap/.style =
{
header=false,
column type={p{0.4cm}},
display columns/0/.style={column name=$\phantom{x}$},
display columns/1/.style={column name=$\phantom{x}$},
display columns/2/.style={column name=$\phantom{x}$},
display columns/3/.style={column name=$\phantom{x}$},
display columns/4/.style={column name=$\phantom{x}$},
display columns/5/.style={column name=$\phantom{x}$},
display columns/6/.style={column name=$\phantom{x}$},
display columns/7/.style={column name=$\phantom{x}$},
display columns/8/.style={column name=$\phantom{x}$},
display columns/9/.style={column name=$\phantom{x}$},
display columns/10/.style={column name=$\phantom{x}$},
postproc cell content/.code=
{%
\pgfkeysalso{/pgfplots/table/@cell content=\pgfmathparse{#1} \edef\multFact{\pgfmathresult} \pgfmathparse{round(##1*\multFact)} \edef\x{\pgfmathresult} \pgfmathtruncatemacro{\y}{\x}

\rule{0cm}{2.4ex}%\y,\y,\y}
\ifnum\y<0 \color{lightgray}\cellcolor{lightgray}\fi
\ifnum\y>0 \ifnum\y <6 \color{myFlowTableTextCol}\cellcolor{myFlowTableBgCol!36}\fi\fi
...
\y
},
},
/pgfplots/table/heatmap/.default=100
}

...
\pgfplotstabletypeset[heatmap=162]{data.dat}

even allows you to preprocess (multiply in this case) the data before colouring the heatmap. Especially for pgf versions < 1.5 this can be hard otherwise.

share|improve this answer
add comment

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.