pgfplotstable allows you to typeset a table in LaTeX without really typing out the table. The following is a simple example, that converts a CSV into a table:

\documentclass{article}
\usepackage{pgfplotstable,booktabs}
\usepackage{filecontents} % <-- To create files on the fly

\begin{filecontents*}{data.csv}
,M23,F231,M36,F44,F63,M70
M23,1.00,0.81,0.88,0.83,0.41,0.82
F231,,1.00,0.52,0.56,0.25,0.94
M36,,,1.00,0.62,0.94,0.96
F44,,,,1.00,0.43,0.23
F63,,,,,1.00,0.22
M70,,,,,,1.00
\end{filecontents*}

\begin{document}
\pgfplotstabletypeset[
    col sep = comma,
    string replace*={_}{\textsubscript},
    every head row/.style={before row=\toprule,after row=\midrule},
    every last row/.style={after row=\bottomrule},
    display columns/0/.style={string type,column name={}}
]
{data.csv}

\end{document}

Above, we use the package filecontents to save the inline data into file system. This is just a convenient way to present the CSV data in the same LaTeX code, which normally it should be generated by a separate process. We also note that, in case of CSV column headers, we often contains underscore which is a special character in LaTeX. Therefore, we do a string replace on the data. The rest are just simple table formatting.

More elaborated command to present a table with more formatting:

\usepackage{pgfplotstable}
\usepackage{booktabs}
\usepackage{longtable}
\usepackage{colortbl}

\pgfplotsset{compat=1.16}
\setlength\LTleft{0in}
\setlength\LTright{1.25in}
\setlength\LTpre{0cm}
\setlength\LTpost{0in}
\setcounter{LTchunksize}{100}

\pgfplotstabletypeset[
    col sep=comma,
    outfile=debug.tex,
    string replace*={_}{\textsubscript},
    begin table=\begin{longtable},
    end table=\end{longtable},
    font=\footnotesize,
    %1000 sep={,},
    every head row/.style={
        before row={
            \caption{My data table} \\
            \toprule
            &&&&&&&\multicolumn{8}{c|}{FOOs}
            &\multicolumn{4}{c|}{BARs}&
            \\
        },
        after row={
            \midrule\endhead
            \bottomrule\endfoot
        },
    },
    every last row/.style={after row=\bottomrule},
    empty cells with={-},
    columns/lorem/.style={string type, column type/.add={|}{|}},
    columns/ipsum/.style={string type, column type/.add={}{|}},
    columns/dolor/.style={string type, column type/.add={}{|}},
    columns/sit/.style={string type, column type/.add={}{|}},
    columns/amet/.style={string type, column type/.add={}{|}},
    columns/FOO-1/.style={fixed, fixed zerofill, dec sep align={|c}, precision=2, column name=$T$, column type/.add={}{}}
    columns/FOO-2/.style={fixed, fixed zerofill, dec sep align, precision=2, column name=$T-1$},
    columns/FOO-3/.style={fixed, fixed zerofill, dec sep align, precision=2, column name=$T-7$},
    columns/FOO-4/.style={fixed, fixed zerofill, dec sep align, precision=2, column name=$T-30$, column type/.add={}{|}},
    columns/BAR-1/.style={fixed, fixed zerofill, dec sep align={|c}, precision=4, column name=$T$},
    columns/BAR-2/.style={fixed, fixed zerofill, dec sep align, precision=4, column name=$T-30$, column type/.add={}{|}},
    columns/Date/.style={string type, column type/.add={}{|}},
]
{data.csv}

Note:

  • data is read from file in CSV format by specifying the column separator col sep=comma
  • To save the output of pgfplotstable command, we provide outfile=debug.tex, this helps debugging the generated table code
  • Table is created with begin and end command of environment \begin{longtable}\end{longtable}
  • Table font is overridden
  • There are two rows of headers: The grouping header is defined manually
  • Each column has its type specified (otherwise pgfplotstable tend to expect a number), and column type specified to add vertical lines. Column-specific settings are addressed using the column name as defined in the CSV file
  • Numeric types are presented in fixed point numbers with specified precision. They are also aligned at the decimal point with dec sep align option. In case the column header needs a special type other than c, it is specified as dec sep align={|c}
  • Data column type (which is different from header in case of dec sep align) is overridden with column type/.add={}{|}

We can further add coloring to header rows:

\usepackage[table]{xcolor}
\definecolor{mycolor}{HTML}{D9F8C7}

\pgfplotstabletypeset[
    every head row/.style={
        before row={
            \caption{My data table} \\
            \hline
            \rowcolor{mycolor}
            &&&&&&&\multicolumn{8}{c|}{\textbf{Foos}}
            &\multicolumn{4}{c|}{\textbf{BARs}}&
            \\
            \rowcolor{mycolor}
        },
        after row={
            \hline\endhead
            \hline\endfoot
            \showrowcolors
        },
    },
    columns={Lorem, ipsum, dolor, sit, amet, FOO-1, FOO-2, ...}
]{...}

Above we use the xcolor package with table option to introduce commands like \rowcolor and \cellcolor. We also use columns={...} to select only a subset of columns to print instead of everything from the input CSV.

When we use the pgfplotstable for slightly more complicated table, we will find that the dec sep align can be problematic to use because this will convert into two adjacent columns for the integer part and decimal part of a numeric column. For example, if we want to color a column, it will not be easy to get both columns right, not the mention that when we have multicolumn (such as a group header), we have to count each column as two. Alternative to dec sep align is to make the column in fixed precision and right-aligned:

columns/FOO/.style = {fixed, fixed zerofill, precision=2, column name=$FOO_1$, column type={r}},

For column color, sometimes it is more convenient to define a new column type:

\newcolumntype{x}{>{\columncolor{myColor}}r}
...
columns/BAR/.style = {fixed, fixed zerofill, precision=2, column name=$BAR^1$, column type={x}},

Heat map on table

A greater challenge in using pgfplotstable is to color the table cells with heat map. First, this is how to get value of another cell on the same row, which will make LaTeX slow:

\pgfplotstablegetelem{\pgfplotstablerow}{AnotherColumn}\of\mytable

The table \mytable have to be registered first. The heat map is defined as a spectrum of color and interpolated using a number between a pair of predefined min and max value:

\pgfplotsset{
    colormap={redgreen}{
        rgb255=(223,101,128) % red
        rgb255=(255,255,255) % white
        rgb255=(217,240,163) % green
    }
}

Then we can color the cell with \cellcolor. Below is a full example, with the special tweak to put a dash on an empty cell:

\documentclass[8pt]{extarticle}

% page formatting packages
\usepackage{geometry}
\usepackage{fancyhdr}
\geometry{letterpaper, landscape, top=1in, bottom=1in, right=0.3in, left=0.3in}
\fancypagestyle{front}{
  \fancyhf{}
  \lhead{\today}
  \chead{Example}
  \rhead{}
  \renewcommand{\headrulewidth}{0pt}
}
\pagestyle{front}

\usepackage[table]{xcolor}
\definecolor{headerShade}{HTML}{D9F0D3}
\definecolor{columnGray}{gray}{0.90}

% table typesetting packages
\usepackage{pgfplotstable}
\usepackage{booktabs}
\usepackage{longtable}
\usepackage{colortbl}
\usepackage{array}

\pgfplotsset{compat=1.16}
\setlength\LTleft{0in}
\setlength\LTright{1.25in}
\setlength\LTpre{0cm}
\setlength\LTpost{0in}
\setcounter{LTchunksize}{100}
\newcolumntype{x}{>{\columncolor{columnGray}}r}
\newcolumntype{y}{>{\columncolor{columnGray}}c}
\newcolumntype{?}{!{\vrule width 1pt}}
% color map -- please use ColorBrewer to pick a more appealing color
\pgfplotsset{
    colormap={redgreen}{
        rgb255=(223,101,128) % red
        rgb255=(255,255,255) % white
        rgb255=(217,240,163) % green
    }
}

% font spec
%\usepackage{fontspec}
%\defaultfontfeatures{Mapping=tex-text}
%\setmainfont[Ligatures=TeX]{Inconsolata}
\usepackage{mathspec}
\setallmainfonts(Digits,Latin){Inconsolata}

\setlength{\parindent}{0pt}
\setlength{\parskip}{1em}

\begin{document}
\pgfplotstableread[col sep=comma]{data.csv}\mytable
\pgfplotstabletypeset[
    col sep=comma,
    outfile=debug.tex,
    string replace*={_}{\textsubscript},
    begin table=\begin{longtable},
    end table=\end{longtable},
    font=\footnotesize,
    every head row/.style={
        before row={
            \caption{Everything} \\
            \rowcolor{headerShade}
            &&&&&&\multicolumn{2}{c?}{\textbf{FOO}}&
            \\
            \rowcolor{headerShade}
        },
        after row={
            \endhead
            \hline\endfoot
            \showrowcolors
        },
    },
    every last row/.style={after row=\hline},
    empty cells with={-},
    columns={
        lorem, ipsum, dolor, sit, consectetur, adipiscing, FOO1, FOO2, Date
    },
    columns/lorem/.style={string type, column type={c}},
    columns/ipsum/.style={string type, column type={y}},
    columns/dolor/.style={string type, column type={c}},
    columns/sit/.style={string type, column type={y}},
    columns/consectetur/.style={fixed, fixed zerofill, precision=2, column type={x},
        column type/.add={?}{},
        postproc cell content/.code={%
            \begingroup
            % read the relval
            \pgfplotstablegetelem{\pgfplotstablerow}{heatConsectetur}\of\mytable%
            \let\value=\pgfplotsretval%
            \ifx\value\empty%
                \pgfmathfloatparsenumber{0.5}%
                \pgfmathfloattofixed{\pgfmathresult}%
                \let\value=\pgfmathresult
            \fi%
            % map that value: \pgfmathresult then contains {<R>,<G>,<B>}
            \pgfplotscolormapaccess[0.0:1.0]{\value}{redgreen}%
            % acquire the display value AFTER any preprocessor or typesetter
            \pgfkeysgetvalue{/pgfplots/table/@cell content}\typesetvalue
            % tex-expansion control
            \toks0=\expandafter{\typesetvalue}%
            \xdef\temp{%
                \noexpand\pgfkeysalso{%
                    @cell content={%
                        \noexpand\cellcolor[rgb]{\pgfmathresult}%
                        \the\toks0 %
                    }%
                }%
            }%
            \endgroup
            \temp
        }%
    },
    columns/adipiscing/.style={fixed, fixed zerofill, precision=2, column type={x},
        column type/.add={}{?},
        postproc cell content/.code={%
            \begingroup
            % read the relval
            \pgfplotstablegetelem{\pgfplotstablerow}{heatAdipiscing}\of\mytable%
            \let\value=\pgfplotsretval%
            \ifx\value\empty%
                \pgfmathfloatparsenumber{0.5}%
                \pgfmathfloattofixed{\pgfmathresult}%
                \let\value=\pgfmathresult
            \fi%
            % map that value: \pgfmathresult then contains {<R>,<G>,<B>}
            \pgfplotscolormapaccess[0.0:1.0]{\value}{redgreen}%
            % acquire the display value AFTER any preprocessor or typesetter
            \pgfkeysgetvalue{/pgfplots/table/@cell content}\typesetvalue
            % tex-expansion control
            \toks0=\expandafter{\typesetvalue}%
            \xdef\temp{%
                \noexpand\pgfkeysalso{%
                    @cell content={%
                        \noexpand\cellcolor[rgb]{\pgfmathresult}%
                        \the\toks0 %
                    }%
                }%
            }%
            \endgroup
            \temp
        }%
    },
    columns/FOO1/.style={fixed, fixed zerofill, precision=4, column name=$T$, column type={x},
        postproc cell content/.code={%
            \begingroup
            % read the relval
            \pgfplotstablegetelem{\pgfplotstablerow}{heatFOO1}\of\mytable%
            \let\value=\pgfplotsretval%
            \ifx\value\empty%
                \pgfmathfloatparsenumber{0.5}%
                \pgfmathfloattofixed{\pgfmathresult}%
                \let\value=\pgfmathresult
            \fi%
            % map that value: \pgfmathresult then contains {<R>,<G>,<B>}
            \pgfplotscolormapaccess[0.0:1.0]{\value}{redgreen}%
            % acquire the display value AFTER any preprocessor or typesetter
            \pgfkeysgetvalue{/pgfplots/table/@cell content}\typesetvalue
            % tex-expansion control
            \toks0=\expandafter{\typesetvalue}%
            \xdef\temp{%
                \noexpand\pgfkeysalso{%
                    @cell content={%
                        \noexpand\cellcolor[rgb]{\pgfmathresult}%
                        \the\toks0 %
                    }%
                }%
            }%
            \endgroup
            \temp
        }%
    },
    columns/FOO2/.style ={fixed, fixed zerofill, precision=4, column name=$T^2$, column type={x},
        column type/.add={}{?},
        postproc cell content/.code={%
            \begingroup
            % read the relval
            \pgfplotstablegetelem{\pgfplotstablerow}{rvWAS-30}\of\mytable%
            \let\value=\pgfplotsretval%
            \ifx\value\empty%
                \pgfmathfloatparsenumber{0.5}%
                \pgfmathfloattofixed{\pgfmathresult}%
                \let\value=\pgfmathresult
            \fi%
            % map that value: \pgfmathresult then contains {<R>,<G>,<B>}
            \pgfplotscolormapaccess[0.0:1.0]{\value}{redgreen}%
            % acquire the display value AFTER any preprocessor or typesetter
            \pgfkeysgetvalue{/pgfplots/table/@cell content}\typesetvalue
            % tex-expansion control
            \toks0=\expandafter{\typesetvalue}%
            \xdef\temp{%
                \noexpand\pgfkeysalso{%
                    @cell content={%
                        \noexpand\cellcolor[rgb]{\pgfmathresult}%
                        \the\toks0 %
                    }%
                }%
            }%
            \endgroup
            \temp
        }%
    },
    columns/Date/.style={string type, column type={c}},
]\mytable


\end{document}

References