2

I know there exists pgf, and many people uses this to create heatmaps. I however am not allowed to use this package. I therefore want to create a command that enables me to color the different cells.

I found this question, that showed the following def

\def\cca#1{\cellcolor{black!#10}\ifnum #1>5\color{white}\fi{#1}}

But it does only work from 0-9 as per his comments and my tests.

I wanted to create something more generic like this pseudo code:

\newcommand{\cTab}[2]
{
    \res = #1/#2 %maybe using FP (?)
    \eighty = 0.8*#2 %maybe using FP (?)

    \cellcolor{black!\res} 
    \ifnum #1>\eighty 
       \color{white}
    \fi{#1}
}

So basicly the issue is to calculate a number and then reuse it to define color and other?

I can calculate the number using FP, but not reuse it within cellcolor or ifnum.

MWE

\documentclass[letterpaper, 10 pt]{article}

% Color
\usepackage{xcolor,colortbl}%

\begin{document}
\begin{table}[!ht]
\centering
\caption{True data classification.}
\label{tab:CollectedErrors}
\begin{tabular}{|p{1.5cm}|p{0.5cm}|}
\hline
\textbf{Exposure}& \textbf{Attribute} \\ \hline

  4 & 2 \\ \hline
   11 &144 \\ \hline 
\end{tabular}
\end{table}
\end{document}

Basicly what I want is to create a heatmap, i.e. color cells based on the number within the cell in the table.

MWE using code from solution 1

\documentclass[letterpaper, 10 pt]{article}

% Color
\usepackage{xcolor,colortbl}%
\usepackage{xintexpr}

\newcommand{\cTab}[2]
{%
    \edef\res    {\xinttheiexpr [2] #1/#2\relax}% [2] = "two digits after ."
    \edef\eighty {\xinttheiexpr [2] 0.8*#2\relax}%
    \cellcolor{black!\res}%
    \xintifboolexpr {#1>\eighty}
        % yes branch 
           {\color{white}}
        % no branch (nothing to do)
           {}% 
    {#1}%
}%

\begin{document}
\begin{table}[!ht]
\centering
\caption{True data classification.}
\label{tab:CollectedErrors}
\begin{tabular}{|p{1.5cm}|p{0.5cm}|}
\hline
\textbf{Exposure}& \textbf{Attribute} \\ \hline

  \cTab{4}{4} & 2 \\ \hline %example, could also be \cTab{4}{144}, in theory all cells should be changed to cTab
   11 &144 \\ \hline 
\end{tabular}
\end{table}
\end{document}
JTIM
  • 2,869
  • 1
    \ifnum does only work for integer numbers,not for floating point –  Feb 15 '16 at 11:53
  • 1
    I don't know if you are tied to tabular or not, but here are two questions that show other approaches: http://tex.stackexchange.com/questions/172578/simplest-way-to-create-a-grid-with-colored-squares-and-labels and http://tex.stackexchange.com/questions/157080/can-tikz-create-pixel-art-images – Steven B. Segletes Feb 15 '16 at 14:51
  • @StevenB.Segletes I have been told that I am constrained by the tabular environment, unfortunately. I found many other examples as you also mention. – JTIM Feb 15 '16 at 14:54

1 Answers1

4

You could try

\usepackage{xintexpr}

\newcommand{\cTab}[2]
{%
    \edef\res    {\xinttheiexpr [2] #1/#2\relax}% [2] = "two digits after ."
    \edef\eighty {\xinttheiexpr [2] 0.8*#2\relax}%
    \cellcolor{black!\res}%
    \xintifboolexpr {#1>\eighty}
    % yes branch 
       {\color{white}}
    % no branch (nothing to do)
       {}% 
    {#1}%
}%

But a mwe would help. Ok, mwe showed I needed \xdef\res but I am quite in the dark about what is aimed at. Update to explain I better understand now... (I was confused about xcolor color specification with a ! as I was led to believe it needed a number between 0 and 1, whereas a percentage between 0 and 100 is asked for).

Updated to avoid defining macros \res and \eighty (especially \res was annoying as it needed a global scope; but we can use expandability of \xinttheiexpr here).

\documentclass[letterpaper, 10 pt]{article}

% Color
\usepackage{xcolor,colortbl}

% Fine stuff
\usepackage{xintexpr, xinttools}

\newcommand{\cTab}[2]% #1 = cell, #2 = max
{%
    \cellcolor{black!\xinttheiexpr 100*#1/#2\relax}%
    \xintifboolexpr {#1>0.8*#2}%
    % "yes" branch 
       {\textcolor{blue}{#1}}% when #1 is big, print it blue
    % "no" branch
       {#1}% 
}%

\begin{document}
\begin{table}[!ht]
\centering
\caption{True data classification.}
\label{tab:CollectedErrors}
\smallskip
\begin{tabular}{|p{1.5cm}|c|}
\hline
\textbf{Exposure}& \textbf{Attribute} \\ \hline
\xintFor* #1 in {\xintSeq[3]{1}{100}}\do
{%
  \cTab{#1}{100} & \cTab{\the\numexpr100-#1\relax}{100}\\
}
\hline 
\end{tabular}
\end{table}
\end{document}

Notice also the use of \textcolor.

Blockquote

  • a mwe, what do you mean ? Your example seems to be exactly what I want. I will try this now. – JTIM Feb 15 '16 at 14:22
  • 1
    a minimal working example means a small document starting with \documentclass and ending with \end{document} which one can copy paste and check. I have no idea where your command \cTab is used ... –  Feb 15 '16 at 14:28
  • I have updated the question with a MWE now. Furthermore I tested the solution by changing one cell and inserting another value, but I get an error: ! Undefined control sequence. black!\res \cTab{4}{4} &

    I have seen the other solution that refers to a \def instead of a command, I do not know if this is needed within a tabular environment?

    – JTIM Feb 15 '16 at 14:50
  • 1
    your mwe does not show \cTab and where it is supposed to be use. Can you post the code which leads to the error you mention ? –  Feb 15 '16 at 14:59
  • I have created a MWE with the code and everything – JTIM Feb 15 '16 at 15:04
  • Indeed you guessed right that the \def was not enough there (it is the same as \newcommand*, basically) due to tabular. But it is still not quite clear what you want. –  Feb 15 '16 at 15:13
  • there is something fishy with your \color{red!\res} but don't have time to check now. –  Feb 15 '16 at 15:19
  • Lets imagine the I have a large table of lot of number ranging from 1 to 1000. A user in a large table has hard time seeing which numbers are what. Therefore using cellcolor, the user can see the darker the cell the higher the number, this is the basic goal. I therefore need to specify for each cell the cell number and the maximum number of all the cells (1000, from the example here). THen the function should fill that particular cell with the correct graident. Is this more clear? – JTIM Feb 15 '16 at 15:21
  • all the cells are independent it is just a heatmap I want to create. – JTIM Feb 15 '16 at 15:22
  • Your solution works now, I just edited some small stuff. – JTIM Feb 15 '16 at 15:30
  • 1
    @JTIM yes, I understand now. Will try to update with a better example. If you needed the tabular to determine itself the maximum number inside the cells, that would make for another interesting question ... ;-) –  Feb 15 '16 at 15:48
  • From your code I thought you wanted black!0.66 but checking xcolor I see that black!66 is what you want. –  Feb 15 '16 at 15:53
  • yeah sorry, my pseudo code was too pseudo :) But at least that helped a lot !! If you want to battle with the other question I will be more than happy to ask it :) It would be cool to have. But I am unsure how to do it without building at least two times? – JTIM Feb 15 '16 at 16:02
  • It depends on the mark-up. For example \DoRows{1&2\\3&4\\5&6} could first compute the max, then produce the rows. –  Feb 15 '16 at 16:06
  • that is of course true, the issue is that then it should also be scalable for not only rows, but also columns. My limited coding experience in latex, I cannot say if it would be hard or easy :) But if you are up for the challenge, I am up for "trying" to formulate a better question with that as a goal :) – JTIM Feb 15 '16 at 16:11
  • 1
    Please look at simplified \cTab macro. No need to define \res and \eighty anymore. –  Feb 15 '16 at 16:16
  • Cool much more simple. The reason for removing the defines is speed or? – JTIM Feb 16 '16 at 07:53
  • speed is hardly an issue, but \res was a problem because it appeared that it had to be defined in a "global" way. Then we should have chosen a better name, for example with @ sign, to reduce chances of overwriting some \res macro used elsewhere in the document. We can make do without ever defining \res because macro \xinttheiexpr has the "expandability" property which allows it to be used almost everywhere in TeX without hickups. –  Feb 16 '16 at 11:02
  • 1
    side note: please note the use of \textcolor. A \color{blue} as in your original code adds some unwanted vertical space due to rather deep TeXnical things. –  Feb 16 '16 at 11:04