6

I have the following problem: I want to color the cells by value; nSHD has values in (0,1) and smaller values should be better so I want values close to 0 to be green while larger values get yellow; TPR, on the other hand has also values in (0,1) but larger values are better so I want the opposite (values close to 1 in green, smaller values yellow); Now the problem is that I don't manage to combine the lines with the color; I started like that:

\documentclass{article}

\usepackage{array} \newcolumntype{?}{!{\vrule width 1.2pt}} \usepackage{collcell}

\usepackage[dvipsnames,table]{xcolor}

\usepackage{multirow} \usepackage{multicol}

\usepackage{pgf} % for calculating the values for gradient %====================================== % Color set related! \definecolor{high}{HTML}{00994d} % the color for the highest number in your data set \definecolor{low}{HTML}{fff51b} % the color for the lowest number in your data set \newcommand{\opacity}{70}% here you can change the opacity of the background color! %====================================== % Data set related! \newcommand{\minval}{0}% define the minimum value on your data set \newcommand{\maxval}{0.25}% define the maximum value in your data set! \newcommand{\minvall}{0.75}% define the minimum value on your data set \newcommand{\maxvall}{1.0}% define the maximum value in your data set! %====================================== % gradient function! \newcommand{\grhigh}[1]{ % The values are calculated linearly between \minval and \maxval \ifdimcomp{#1pt}{>}{\maxvall pt}{#1}{ \ifdimcomp{#1pt}{<}{\minvall pt}{#1}{ \pgfmathparse{int(round(100(#1/(\maxvall-\minvall))-(\minvall(100/(\maxvall-\minvall)))))} \xdef\tempa{\pgfmathresult} \cellcolor{high!\tempa!low!\opacity} #1 }} } \newcommand{\grlow}[1]{ % The values are calculated linearly between \minval and \maxval \ifdimcomp{#1pt}{>}{\maxval pt}{#1}{ \ifdimcomp{#1pt}{<}{\minval pt}{#1}{ \pgfmathparse{int(round(100(#1/(\maxval-\minval))-(\minval*(100/(\maxval-\minval)))))} \xdef\tempa{\pgfmathresult} \cellcolor{low!\tempa!high!\opacity} #1 }} }

\begin{document}

\renewcommand{\arraystretch}{1.6}

\begin{table}[!htbp] \centering \resizebox{\columnwidth}{!}{% \begin{tabular}{|c|c|c|c|c|c?c|c|c|c?c|c|c|c|} \hline \multicolumn{2}{|c|}{$r$} & \multicolumn{4}{c?}{$10%$} & \multicolumn{4}{c?}{$30%$} & \multicolumn{4}{c|}{$50%$} \ \hline \multicolumn{2}{|c|}{$n$} & 50 & 100 & 250 & 500 & 50 & 100 & 250 & 500 & 50 & 100 & 250 & 500 \ \hline \multirow{2}{}{$d=10$} & nSHD & \grlow{0.19} & \grlow{0.11} & \grlow{0.04} & \grlow{0.03} & \grlow{0.13} & \grlow{0.1} & \grlow{0.03} & \grlow{0.03} & \grlow{0.18} & \grlow{0.15} & \grlow{0.09} & \grlow{0.08} \ \cline{2-14} & TPR & \grhigh{0.88} & \grhigh{0.94} & \grhigh{0.97} & \grhigh{0.99} & \grhigh{0.96} & \grhigh{0.98} & \grhigh{0.99} & \grhigh{1.0} & \grhigh{0.91} & \grhigh{0.93} & \grhigh{0.95} & \grhigh{0.94} \ \hline \multirow{2}{}{$d=20$} & nSHD & \grlow{0.11} & \grlow{0.06} & \grlow{0.03} & \grlow{0.02} & \grlow{0.13} & \grlow{0.09} & \grlow{0.06} & \grlow{0.04} & \grlow{0.18} & \grlow{0.14} & \grlow{0.1} & \grlow{0.08} \ \cline{2-14} & TPR & \grhigh{0.94} & \grhigh{0.98} & \grhigh{1.0} & \grhigh{1.0} & \grhigh{0.93} & \grhigh{0.96} & \grhigh{0.98} & \grhigh{0.99} & \grhigh{0.86} & \grhigh{0.92} & \grhigh{0.94} & \grhigh{0.96} \ \hline \multirow{2}{}{$d=30$} & nSHD & \grlow{0.1} & \grlow{0.06} & \grlow{0.03} & \grlow{0.02} & \grlow{0.12} & \grlow{0.08} & \grlow{0.05} & \grlow{0.03} & \grlow{0.15} & \grlow{0.12} & \grlow{0.09} & \grlow{0.07} \ \cline{2-14} & TPR & \grhigh{0.96} & \grhigh{0.97} & \grhigh{0.99} & \grhigh{1.0} & \grhigh{0.93} & \grhigh{0.96} & \grhigh{0.98} & \grhigh{0.99} & \grhigh{0.89} & \grhigh{0.9} & \grhigh{0.95} & \grhigh{0.96} \ \hline \end{tabular} } \vspace{2mm} \caption{Some Caption.} \end{table}

\end{document}

This worked well for the colors but it does not draw the lines properly - e.g. when opening with Adobe it looks like that: Missing lines

You can see that the vertical and horizontal lines are not drawn properly; I then searched here on StackExchange and found the following similar question:

Tabular and lines displaying problem with Adobe

Two work arounds were suggested: First, to use the package nicematrix which did not work and then to draw the table twice: Once with colors and once without it; Based on this answer, I tried that:

\documentclass{article}

\usepackage{array} \newcolumntype{?}{!{\vrule width 1.2pt}} \usepackage{collcell}

\usepackage[dvipsnames,table]{xcolor}

\usepackage{multirow} \usepackage{multicol}

\usepackage{pgf} % for calculating the values for gradient %====================================== % Color set related! \definecolor{high}{HTML}{00994d} % the color for the highest number in your data set \definecolor{low}{HTML}{fff51b} % the color for the lowest number in your data set \newcommand{\opacity}{70}% here you can change the opacity of the background color! %====================================== % Data set related! \newcommand{\minval}{0}% define the minimum value on your data set \newcommand{\maxval}{0.25}% define the maximum value in your data set! \newcommand{\minvall}{0.75}% define the minimum value on your data set \newcommand{\maxvall}{1.0}% define the maximum value in your data set! %====================================== % gradient function! \newcommand{\grhigh}[1]{ % The values are calculated linearly between \minval and \maxval \ifdimcomp{#1pt}{>}{\maxvall pt}{#1}{ \ifdimcomp{#1pt}{<}{\minvall pt}{#1}{ \pgfmathparse{int(round(100(#1/(\maxvall-\minvall))-(\minvall(100/(\maxvall-\minvall)))))} \xdef\tempa{\pgfmathresult} \cellcolor{high!\tempa!low!\opacity} #1 }} } \newcommand{\grlow}[1]{ % The values are calculated linearly between \minval and \maxval \ifdimcomp{#1pt}{>}{\maxval pt}{#1}{ \ifdimcomp{#1pt}{<}{\minval pt}{#1}{ \pgfmathparse{int(round(100(#1/(\maxval-\minval))-(\minval*(100/(\maxval-\minval)))))} \xdef\tempa{\pgfmathresult} \cellcolor{low!\tempa!high!\opacity} #1 }} }

\begin{document}

\renewcommand{\arraystretch}{1.6}

\begin{table}[!htbp] \centering \resizebox{\columnwidth}{!}{% \def\tmp{ \begin{tabular}{|c|c|c|c|c|c?c|c|c|c?c|c|c|c|} \hline \multicolumn{2}{|c|}{$r$} & \multicolumn{4}{c?}{$10%$} & \multicolumn{4}{c?}{$30%$} & \multicolumn{4}{c|}{$50%$} \ \hline \multicolumn{2}{|c|}{$n$} & 50 & 100 & 250 & 500 & 50 & 100 & 250 & 500 & 50 & 100 & 250 & 500 \ \hline \multirow{2}{}{$d=10$} & nSHD & \grlow{0.19} & \grlow{0.11} & \grlow{0.04} & \grlow{0.03} & \grlow{0.13} & \grlow{0.1} & \grlow{0.03} & \grlow{0.03} & \grlow{0.18} & \grlow{0.15} & \grlow{0.09} & \grlow{0.08} \ \cline{2-14} & TPR & \grhigh{0.88} & \grhigh{0.94} & \grhigh{0.97} & \grhigh{0.99} & \grhigh{0.96} & \grhigh{0.98} & \grhigh{0.99} & \grhigh{1.0} & \grhigh{0.91} & \grhigh{0.93} & \grhigh{0.95} & \grhigh{0.94} \ \hline \multirow{2}{}{$d=20$} & nSHD & \grlow{0.11} & \grlow{0.06} & \grlow{0.03} & \grlow{0.02} & \grlow{0.13} & \grlow{0.09} & \grlow{0.06} & \grlow{0.04} & \grlow{0.18} & \grlow{0.14} & \grlow{0.1} & \grlow{0.08} \ \cline{2-14} & TPR & \grhigh{0.94} & \grhigh{0.98} & \grhigh{1.0} & \grhigh{1.0} & \grhigh{0.93} & \grhigh{0.96} & \grhigh{0.98} & \grhigh{0.99} & \grhigh{0.86} & \grhigh{0.92} & \grhigh{0.94} & \grhigh{0.96} \ \hline \multirow{2}{}{$d=30$} & nSHD & \grlow{0.1} & \grlow{0.06} & \grlow{0.03} & \grlow{0.02} & \grlow{0.12} & \grlow{0.08} & \grlow{0.05} & \grlow{0.03} & \grlow{0.15} & \grlow{0.12} & \grlow{0.09} & \grlow{0.07} \ \cline{2-14} & TPR & \grhigh{0.96} & \grhigh{0.97} & \grhigh{0.99} & \grhigh{1.0} & \grhigh{0.93} & \grhigh{0.96} & \grhigh{0.98} & \grhigh{0.99} & \grhigh{0.89} & \grhigh{0.9} & \grhigh{0.95} & \grhigh{0.96} \ \hline \end{tabular} } \leavevmode \rlap{\tmp}% \begingroup \renewcommand{\cellcolor}[1]{}% \tmp \endgroup } \vspace*{2mm} \caption{Some Caption.} \end{table}

\end{document}

Eberything Bold

We can see that if drawing the table twice, the numbers and also the lines become very thick; Does anyone have a solution for this problem?

Ivan
  • 67
  • What exactly "did not work" using nicematrix? – Jasper Habicht Oct 11 '22 at 11:14
  • @JasperHabicht If I used the option [hvlines] as in the other question, it mixed up the alignment and it was a complete mess; If I not included it, then the lines were missing.. Do you want me to extent the question and illustrate how it looks like with nicematrix? – Ivan Oct 11 '22 at 11:29
  • 1
    The problem seems to be with the \clines, at least on my system. I got a good result with \usepackage{hhline} and replacing \cline{2-14}\hhline{~-------------}. Your mileage may vary, however. – Pieter van Oostrum Oct 11 '22 at 11:49
  • @PietervanOOstrum You mean for the first code or where did you use hhline instead of cline and received good results? – Ivan Oct 11 '22 at 12:04
  • With nicematrix, I cannot get the colors right, as they seem not to be calculated on the fly. Strange ... – Jasper Habicht Oct 11 '22 at 13:11
  • @Ivan, yes that's what I meant. I only looked at the first code. – Pieter van Oostrum Oct 11 '22 at 18:10

2 Answers2

5

This is an approach using the tabularray package which does not have the problem that lines are covered by the cell color:

\documentclass{article}
\usepackage[margin=2cm]{geometry}

\usepackage{tabularray} \UseTblrLibrary{functional}

\usepackage{pgf} % for calculating the values for gradient %====================================== % Color set related! \definecolor{high}{HTML}{00994d} % the color for the highest number in your data set \definecolor{low}{HTML}{fff51b} % the color for the lowest number in your data set \pgfmathtruncatemacro{\opacity}{70} % here you can change the opacity of the background color! %====================================== % Data set related! \pgfmathsetmacro{\minval}{0}% define the minimum value on your data set \pgfmathsetmacro{\maxval}{0.25}% define the maximum value in your data set! \pgfmathsetmacro{\minvall}{0.75}% define the minimum value on your data set \pgfmathsetmacro{\maxvall}{1.0}% define the maximum value in your data set! %====================================== % gradient function! \IgnoreSpacesOn \prgNewFunction \grhighlowColor {} { \intStepOneInline {3} {\arabic{rowcount}} { \intSet \lTmpaInt { \intMathMod {##1} {2} } \intCompareTF {\lTmpaInt} = {1} { \intStepOneInline {3} {\arabic{colcount}} { \tlSet \lTmpbTl {\cellGetText {##1} {####1}} \fpCompareTF {\lTmpbTl} > {\maxval} { } { \fpCompareTF {\lTmpbTl} < {\minval} { } { \pgfmathparse{int(round(100(\lTmpbTl/(\maxval-\minval))-(\minval(100/(\maxval-\minval)))))} \cellSetStyle {##1} {####1} {bg=low!\pgfmathresult!high!\opacity} } } } } { \intStepOneInline {3} {\arabic{colcount}} { \tlSet \lTmpbTl {\cellGetText {##1} {####1}} \fpCompareTF {\lTmpbTl} > {\maxvall} { } { \fpCompareTF {\lTmpbTl} < {\minvall} { } { \pgfmathparse{int(round(100(\lTmpbTl/(\maxvall-\minvall))-(\minvall(100/(\maxvall-\minvall)))))} \cellSetStyle {##1} {####1} {bg=high!\pgfmathresult!low!\opacity} } } } } } } \IgnoreSpacesOff

\begin{document}

\begin{table}\footnotesize \begin{tblr}{ colspec = { {2}{c} {12}{X[c]} }, hlines, vlines, vline{7,11} = {1.2pt}, process=\grhighlowColor } \SetCell[c=2]{} $r$ & & \SetCell[c=4]{} $10%$ & & & & \SetCell[c=4]{} $30%$ & & & & \SetCell[c=4]{} $50%$ & & & \ \SetCell[c=2]{} $n$ & & 50 & 100 & 250 & 500 & 50 & 100 & 250 & 500 & 50 & 100 & 250 & 500 \ \SetCell[r=2]{} $d=10$ & nSHD & 0.19 & 0.11 & 0.04 & 0.03 & 0.13 & 0.1 & 0.03 & 0.03 & 0.18 & 0.15 & 0.09 & 0.08 \ & TPR & 0.88 & 0.94 & 0.97 & 0.99 & 0.96 & 0.98 & 0.99 & 1.0 & 0.91 & 0.93 & 0.95 & 0.94 \ \SetCell[r=2]{} $d=20$ & nSHD & 0.11 & 0.06 & 0.03 & 0.02 & 0.13 & 0.09 & 0.06 & 0.04 & 0.18 & 0.14 & 0.1 & 0.08 \ & TPR & 0.94 & 0.98 & 1.0 & 1.0 & 0.93 & 0.96 & 0.98 & 0.99 & 0.86 & 0.92 & 0.94 & 0.96 \ \SetCell[r=2]{} $d=30$ & nSHD & 0.1 & 0.06 & 0.03 & 0.02 & 0.12 & 0.08 & 0.05 & 0.03 & 0.15 & 0.12 & 0.09 & 0.07 \ & TPR & 0.96 & 0.97 & 0.99 & 1.0 & 0.93 & 0.96 & 0.98 & 0.99 & 0.89 & 0.9 & 0.95 & 0.96 \ \end{tblr} \vspace*{2mm} \caption{Some Caption.} \end{table}

\end{document}

enter image description here

3

In order to have a perfect output with {NiceTabular} of nicematrix, one should not use \cline which is a command of standard LaTeX (and has not been redefined by nicematrix). However, there is no need to use \cline if the command \Block of nicematrix is used: the horizontal and vertical rules are not drawn in the blocks...

\documentclass{article}

\usepackage{collcell}

\usepackage[dvipsnames,table]{xcolor}

\usepackage{nicematrix,tikz}

\usepackage{pgf} % for calculating the values for gradient %====================================== % Color set related! \definecolor{high}{HTML}{00994d} % the color for the highest number in your data set \definecolor{low}{HTML}{fff51b} % the color for the lowest number in your data set \newcommand{\opacity}{70}% here you can change the opacity of the background color! %====================================== % Data set related! \newcommand{\minval}{0}% define the minimum value on your data set \newcommand{\maxval}{0.25}% define the maximum value in your data set! \newcommand{\minvall}{0.75}% define the minimum value on your data set \newcommand{\maxvall}{1.0}% define the maximum value in your data set! %====================================== % gradient function! \newcommand{\grhigh}[1]{ % The values are calculated linearly between \minval and \maxval \ifdimcomp{#1pt}{>}{\maxvall pt}{#1}{ \ifdimcomp{#1pt}{<}{\minvall pt}{#1}{ \pgfmathparse{int(round(100(#1/(\maxvall-\minvall))-(\minvall(100/(\maxvall-\minvall)))))} \xdef\tempa{\pgfmathresult} \cellcolor{high!\tempa!low!\opacity} #1 }} } \newcommand{\grlow}[1]{ % The values are calculated linearly between \minval and \maxval \ifdimcomp{#1pt}{>}{\maxval pt}{#1}{ \ifdimcomp{#1pt}{<}{\minval pt}{#1}{ \pgfmathparse{int(round(100(#1/(\maxval-\minval))-(\minval*(100/(\maxval-\minval)))))} \xdef\tempa{\pgfmathresult} \cellcolor{low!\tempa!high!\opacity} #1 }} }

\begin{document}

\renewcommand{\arraystretch}{1.6}

\NiceMatrixOptions { custom-line = { letter = ? , total-width = 1.2 pt , tikz = { line width = 1.2 pt } } }

\begin{table}[!htbp] \centering \resizebox{\columnwidth}{!}{% \begin{NiceTabular}{|c|c|c|c|c|c?c|c|c|c?c|c|c|c|}[hlines] \Block{1-2}{$r$} && \Block{1-4}{$10%$} &&&& \Block{1-4}{$30%$} &&&& \Block{1-4}{$50%$} \ \Block{1-2}{$n$} && 50 & 100 & 250 & 500 & 50 & 100 & 250 & 500 & 50 & 100 & 250 & 500 \ \Block{2-1}{$d=10$} & nSHD & \grlow{0.19} & \grlow{0.11} & \grlow{0.04} & \grlow{0.03} & \grlow{0.13} & \grlow{0.1} & \grlow{0.03} & \grlow{0.03} & \grlow{0.18} & \grlow{0.15} & \grlow{0.09} & \grlow{0.08} \ & TPR & \grhigh{0.88} & \grhigh{0.94} & \grhigh{0.97} & \grhigh{0.99} & \grhigh{0.96} & \grhigh{0.98} & \grhigh{0.99} & \grhigh{1.0} & \grhigh{0.91} & \grhigh{0.93} & \grhigh{0.95} & \grhigh{0.94} \ \Block{2-1}{$d=20$} & nSHD & \grlow{0.11} & \grlow{0.06} & \grlow{0.03} & \grlow{0.02} & \grlow{0.13} & \grlow{0.09} & \grlow{0.06} & \grlow{0.04} & \grlow{0.18} & \grlow{0.14} & \grlow{0.1} & \grlow{0.08} \ & TPR & \grhigh{0.94} & \grhigh{0.98} & \grhigh{1.0} & \grhigh{1.0} & \grhigh{0.93} & \grhigh{0.96} & \grhigh{0.98} & \grhigh{0.99} & \grhigh{0.86} & \grhigh{0.92} & \grhigh{0.94} & \grhigh{0.96} \ \Block{2-1}{$d=30$} & nSHD & \grlow{0.1} & \grlow{0.06} & \grlow{0.03} & \grlow{0.02} & \grlow{0.12} & \grlow{0.08} & \grlow{0.05} & \grlow{0.03} & \grlow{0.15} & \grlow{0.12} & \grlow{0.09} & \grlow{0.07} \ & TPR & \grhigh{0.96} & \grhigh{0.97} & \grhigh{0.99} & \grhigh{1.0} & \grhigh{0.93} & \grhigh{0.96} & \grhigh{0.98} & \grhigh{0.99} & \grhigh{0.89} & \grhigh{0.9} & \grhigh{0.95} & \grhigh{0.96} \ \end{NiceTabular} } \vspace*{2mm} \caption{Some Caption.} \end{table}

\end{document}

As usual with nicematrix, several compilations are necessary.

Output of the above code

F. Pantigny
  • 40,250