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 have a following command in my latex document:

\newcommand{\ApplyGradient}[1]{
              \pgfmathsetmacro{\PercentColor}{100.0*(#1+0.2)/1.3}
              \textcolor{black!\PercentColor}{#1}}


\newcolumntype{R}{>{\collectcell\ApplyGradient}{r}<{\endcollectcell}}

I use this code to color my tables with shades of gray depending on the value within each cell of the table. It is similar to how conditional formatting works in MS Excel. However, I encountered table that also contains NaNs. Is there a way to adapt this code so that it would display text correctly?

PS: Example:

\documentclass[a4paper,12pt]{report}
\usepackage[english]{babel}   

\usepackage{pgf}    
\usepackage{collcell} 

\newcommand{\ApplyGradient}[1]{%
    \pgfmathsetmacro{\PercentColor}{100.0*(#1+0.2)/1.3}
    \textcolor{black!\PercentColor}{#1}}
\newcolumntype{R}{>{\collectcell\ApplyGradient}{r}<{\endcollectcell}}

\begin{document}
\begin{table}[htbp]
\begin{tabular}{lRRr}
p2p & 0.08 & 0.74 & 10\\
p2p like dest & 0.67 & 0.25 & 185\\
%scan sql & 0.01 & NaN & 23\\
skype s.d. & 0.67 & 0.71 & 80\\
\end{tabular}
\end{table}
\end{document}

Uncommenting the commented line gives the error.

PPS: I just found an easy solution: encapsulating the cell in \multicolumn{1}{r}{ NaN} solves the problem :-)

share|improve this question

3 Answers 3

up vote 5 down vote accepted

pgf provides the functionality to check whether \pgfmathresult is a number or not using \pgfmathfloatparsenumber and checking \F of

\pgfmathfloattomacro{\pgfmathresult}{\F}{\M}{\E}

(which separates \pgfmathresult into "components"):

enter image description here

\documentclass{article}
\usepackage{pgf,collcell}% http://ctan.org/pkg/{pgf,collcell}

\newcommand{\ApplyGradient}[1]{%
  \pgfmathfloatparsenumber{#1}% Parse float
  \pgfmathfloattomacro{\pgfmathresult}{\F}{\M}{\E}% Break result into components
  \ifnum\F=3\relax% Test flag for sign/number type (3 = NaN)
    \textcolor{red}{#1}%
  \else%
    \pgfmathsetmacro{\PercentColor}{100.0*(#1+0.2)/1.3}%
    \textcolor{black!\PercentColor}{#1}%
  \fi}
\newcolumntype{R}{>{\collectcell\ApplyGradient}{r}<{\endcollectcell}}

\begin{document}
\begin{tabular}{lRRr}
  p2p           & 0.08 & 0.74 &  10 \\
  p2p like dest & 0.67 & 0.25 & 185 \\
  scan sql      & 0.01 &  NaN &  23 \\
  skype s.d.    & 0.67 & 0.71 &  80
\end{tabular}
\end{document}
share|improve this answer
    
There’s \pgfmathfloatgetflagstomacro\pgfmathresult\F (or \pfgmathfloatgetflags (to a count register)) and especially \pgfmathfloatifflags\pgfmathresult 3{<true>}{<false>} which uses \pgfmathfloatgetflagstomacro internally. –  Qrrbrbirlbel May 26 '13 at 20:48
    
Thank you for your answer! Pgf has a lot more depth to it than I thought. –  BoZenKhaa May 26 '13 at 21:17

You can compare the argument with NaN:

\documentclass[a4paper,12pt]{report}
\usepackage[english]{babel}

\usepackage{pgf}
\usepackage{collcell}

\newcommand{\ApplyGradient}[1]{%
  \ifnum\pdfstrcmp{#1}{NaN}=0
    #1%
  \else
    \pgfmathsetmacro{\PercentColor}{100.0*(#1+0.2)/1.3}%
    \textcolor{black!\PercentColor}{#1}%
  \fi}
\newcolumntype{R}{>{\collectcell\ApplyGradient}{r}<{\endcollectcell}}

\begin{document}
\begin{table}[htbp]
\begin{tabular}{lRRr}
p2p & 0.08 & 0.74 & 10\\
p2p like dest & 0.67 & 0.25 & 185\\
scan sql & 0.01 & NaN & 23\\
skype s.d. & 0.67 & 0.71 & 80\\
\end{tabular}
\end{table}
\end{document}

You can add any formatting you want in the "true" branch of the conditional, for instance \textcolor{red}{#1} instead of just #1.

If you plan to use the macros also with LuaLaTeX or XeLaTeX, then do

\usepackage{pdftexcmds}
\makeatletter
\newcommand{\ApplyGradient}[1]{%
  \ifnum\pdf@strcmp{#1}{NaN}=\z@
    #1%
  \else
    \pgfmathsetmacro{\PercentColor}{100.0*(#1+0.2)/1.3}%
    \textcolor{black!\PercentColor}{#1}%
  \fi}
\makeatletter
share|improve this answer
    
Thank you for the answer! I was not aware it was possible to use if/then construct in latex. –  BoZenKhaa May 26 '13 at 21:15

Probably not that practical if this is a single use case but if you have quite a few number of NaN's, pgfplotstable does this check internally and you just provide the data and the relevant styles.

\documentclass{standalone}
\usepackage{pgfplotstable}

\pgfplotsset{compat=1.8,%just to supress warnings
     table/adjust the opacity/.style={
        postproc cell content/.append code={%
             \pgfkeysgetvalue{/pgfplots/table/@preprocessed cell content}\pgfmathresult%
             \ifx\pgfmathresult\empty\relax
             \else%
                 \pgfmathparse{100.0*(\pgfmathresult+0.2)/1.3}
                \begingroup\edef\temp{\endgroup%
                 \noexpand\pgfkeys{/pgfplots/table/@cell content/.add={\noexpand\color{black!\pgfmathresult}}{}}%
                }\temp
             \fi%
        },
    }
}



\begin{document}

\pgfplotstabletypeset[
header=false, %Columns have no header rows
every head row/.style={output empty row},% ALso we don't need a header row
display columns/0/.style={string type,column type=l},% First column is treated as text
display columns/1/.style={column type=r,fixed,adjust the opacity}, 
display columns/2/.style={
    column type=r,
    clear infinite,% Clear the infinities and Nans
    adjust the opacity, % Our style
    empty cells with={NaN},% If empty cell place a NaN
},
display columns/3/.style={column type=r}, 
]{
p2p             0.08 0.74 10
{p2p like dest} 0.67 0.25 185
{scan sql}      0.01 NaN  23
{skype s.d.}    0.67 0.71 80
}
\end{document}

enter image description here

share|improve this answer
    
Thank you, this is really nice, whole new way to make tables. It is an overkill for me now, but I will keep it in mind for next time when. –  BoZenKhaa May 26 '13 at 21:58

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.