¿Por qué falla `datatool` cuando se usa en una figura de Tikz?

¿Por qué falla `datatool` cuando se usa en una figura de Tikz?

Considere el siguiente ejemplo

\documentclass[varwidth=true, border=2pt]{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{datatool}

\begin{filecontents*}[overwrite]{test.csv}
Actual,Class 1,Class 2,Class 3
Class 1,1480.0,0.0,125.0
Class 2,112.0,1303.0,180.0
Class 3,174.0,95.0,1331.0    
\end{filecontents*}

\DTLloaddb[keys={Actual,Class 1,Class 2,Class 3}]% <options>
{test}% <db name>
{test.csv}% <filename>

\newcommand{\fetchdata}[2]{\DTLfetch{test}{Actual}{Class #1}{Class #2}}

\pgfplotsset{compat=1.17}
\begin{document}

Hi \fetchdata{1}{1}

\begin{tikzpicture}
    \begin{axis}[
            colormap={bluewhite}{color=(white) rgb255=(90,96,191)},
            xlabel=Predicted,
            xlabel style={yshift=-30pt},
            ylabel=Actual,
            ylabel style={yshift=20pt},
            xticklabels={Class 1, Class 2, Class 3}, % changed
            xtick={0,...,2}, % changed
            xtick style={draw=none},
            yticklabels={Class 1, Class 2, Class 3}, % changed
            ytick={0,...,2}, % changed
            ytick style={draw=none},
            enlargelimits=false,
            colorbar,
            xticklabel style={
              rotate=00
            },
            nodes near coords={\pgfmathprintnumber\pgfplotspointmeta},
            nodes near coords style={
                yshift=-7pt
            },
        ]
        \addplot[
            matrix plot,
            mesh/cols=3, % changed
            point meta=explicit, draw=gray
        ] table [meta=C] {
            x y C
            0 0 0.5
            1 0 0.01809
            2 0 0.02366
            
            0 1 0.05839
            1 1 0.90109
            2 1 0.01290
            
            0 2 0.06525
            1 2 0.08082
            2 2 0.96344
        };
        
        % Add text in a specific position
        \node[anchor=south, yshift={-20pt}] at (axis cs:0,0) {(1531)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:1,0) {(30)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:2,0) {(33)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:0,1) {(102)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:1,1) {(1494)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:2,1) {(18)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:0,2) {(114)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:1,2) {(134)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:2,2) {(1344)};
    \end{axis}
\end{tikzpicture}
\end{document}

Esto produce

ingrese la descripción de la imagen aquí

Sin embargo, si trato de ponerlo \DTLfetchdentro del tikzpictureentorno, es decir:

\documentclass[varwidth=true, border=2pt]{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{datatool}

\begin{filecontents*}[overwrite]{test.csv}
Actual,Class 1,Class 2,Class 3
Class 1,1480.0,0.0,125.0
Class 2,112.0,1303.0,180.0
Class 3,174.0,95.0,1331.0    
\end{filecontents*}

\DTLloaddb[keys={Actual,Class 1,Class 2,Class 3}]% <options>
{test}% <db name>
{test.csv}% <filename>

\newcommand{\fetchdata}[2]{\DTLfetch{test}{Actual}{Class #1}{Class #2}}

\pgfplotsset{compat=1.17}
\begin{document}

\begin{tikzpicture}
    \begin{axis}[
            colormap={bluewhite}{color=(white) rgb255=(90,96,191)},
            xlabel=Predicted,
            xlabel style={yshift=-30pt},
            ylabel=Actual,
            ylabel style={yshift=20pt},
            xticklabels={Class 1, Class 2, Class 3}, % changed
            xtick={0,...,2}, % changed
            xtick style={draw=none},
            yticklabels={Class 1, Class 2, Class 3}, % changed
            ytick={0,...,2}, % changed
            ytick style={draw=none},
            enlargelimits=false,
            colorbar,
            xticklabel style={
              rotate=00
            },
            nodes near coords={\pgfmathprintnumber\pgfplotspointmeta},
            nodes near coords style={
                yshift=-7pt
            },
        ]
        \addplot[
            matrix plot,
            mesh/cols=3, % changed
            point meta=explicit, draw=gray
        ] table [meta=C] {
            x y C
            0 0 0.5
            1 0 0.\fetchdata{1}{1}
            2 0 0.02366
            
            0 1 0.05839
            1 1 0.90109
            2 1 0.01290
            
            0 2 0.06525
            1 2 0.08082
            2 2 0.96344
        };
        
        % Add text in a specific position
        \node[anchor=south, yshift={-20pt}] at (axis cs:0,0) {(1531)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:1,0) {(30)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:2,0) {(33)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:0,1) {(102)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:1,1) {(1494)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:2,1) {(18)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:0,2) {(114)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:1,2) {(134)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:2,2) {(1344)};
    \end{axis}
\end{tikzpicture}
\end{document}

yo obtengo

Undefined control sequence.
\edtlgetrowforvalue ...def \@dtl@dogetrowforvalueLaTeX
Undefined control sequence.
\edtlgetrowforvalue ...#3}}\@dtl@dogetrowforvalueLaTeX
Undefined control sequence.
\dtlgetentryfromrow ...3->\edef \@dtl@do@getentryLaTeX
Undefined control sequence.
\dtlgetentryfromrow ...\the #3}}\@dtl@do@getentryLaTeX
Undefined control sequence.
\DTLfetch ...olumnindex {#1}{#4}}\dtlcurrentvalueLaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Missing control sequence inserted.
<inserted text>LaTeX
Undefined control sequence.
\dtlgetrowindex ...@ {#4}\edef \dtl@dogetrowindexLaTeX
Undefined control sequence.
\dtlgetrowindex ...he \toks@ }}\dtl@dogetrowindexLaTeX
Undefined control sequence.
\dtlgetrowforvalue ...lse \dtlrownum =\dtl@rowidxLaTeX
Undefined control sequence.
\dtlgetrowforvalue ...idx \relax \edef \dtldbnameLaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Undefined control sequence.
\dtlgetrowforvalue ...csname \edef \@dtl@dogetrowLaTeX
Undefined control sequence.
\dtlgetrowforvalue ... {\the \toks@ }{\dtl@rowidxLaTeX
Undefined control sequence.
\dtlgetrowforvalue ...dtl@rowidx }}\@dtl@dogetrowLaTeX
Extra }, or forgotten \endgroup.
\pgfmathresult ...romrow {\dtlcurrentvalue }{2}{}}LaTeX
Undefined control sequence.
\dtlgetrowindex ...he \toks@ }}\dtl@dogetrowindexLaTeX
Undefined control sequence.
\dtlgetrowforvalue ...lse \dtlrownum =\dtl@rowidxLaTeX
Missing number, treated as zero.
<to be read again>LaTeX
Undefined control sequence.
\dtlgetrowforvalue ...m =\dtl@rowidx \relax \edefLaTeX
Undefined control sequence.
\dtlgetrowforvalue ...idx \relax \edef \dtldbnameLaTeX
Undefined control sequence.
\dtlgetrowforvalue ...me dtldb@#1\endcsname \edefLaTeX
Undefined control sequence.
\dtlgetrowforvalue ...csname \edef \@dtl@dogetrowLaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Missing { inserted.
<to be read again>LaTeX
Undefined control sequence.
\dtlgetrowforvalue ...dtl@rowidx }}\@dtl@dogetrowLaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Undefined control sequence.
\GenericError  ...LaTeX
Undefined control sequence.
\GenericError  ...LaTeX
Missing { inserted.
<to be read again>LaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Missing number, treated as zero.
<to be read again>LaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Extra \fi.
\CheckEncodingSubset ...:\f@family \endcsname \fiLaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Extra \else.
\CheckEncodingSubset ...dafter \@firstoftwo \elseLaTeX
Extra \fi.
<recently read> \fiLaTeX
Argument of \tc@subst has an extra }.
<inserted text>LaTeX
Paragraph ended before \tc@subst was complete.
<to be read again>LaTeX
Extra \fi.
\GenericError ...rstchoice@ \else 6\fi \endcsnameLaTeX
Extra \fi.
\?-cmd ...ndcsname {\TextSymbolUnavailable #1}\fiLaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Extra \fi.
\?-cmd ...endcsname \csname ?\string #1\endcsnameLaTeX
Extra \fi.
\?-cmd ...sname \csname ?\string #1\endcsname \fiLaTeX
Extra \else.
\?-cmd ...\string #1\expandafter \endcsname \elseLaTeX
Extra \fi.
<recently read> \endcsnameLaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Extra \fi.
<recently read> \endcsnameLaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Missing number, treated as zero.
<to be read again>LaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Extra \else.
\CheckEncodingSubset ...name #2:?\endcsname \elseLaTeX
Extra \fi.
\CheckEncodingSubset ...e #2:\f@family \endcsnameLaTeX
Extra \fi.
\CheckEncodingSubset ...:\f@family \endcsname \fiLaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Extra \else.
\CheckEncodingSubset ...dafter \@firstoftwo \elseLaTeX
Extra \fi.
<recently read> \fiLaTeX
Argument of \tc@subst has an extra }.
<inserted text>LaTeX
Paragraph ended before \tc@subst was complete.
<to be read again>LaTeX
Extra \fi.
\GenericError ...rstchoice@ \else 6\fi \endcsnameLaTeX
Extra \fi.
\?-cmd ...ndcsname {\TextSymbolUnavailable #1}\fiLaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Extra \fi.
\?-cmd ...endcsname \csname ?\string #1\endcsnameLaTeX
Extra \fi.
\?-cmd ...sname \csname ?\string #1\endcsname \fiLaTeX
Extra \else.
\?-cmd ...\string #1\expandafter \endcsname \elseLaTeX
Extra \fi.
<recently read> \endcsnameLaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Extra \fi.
<recently read> \endcsnameLaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Missing number, treated as zero.
<to be read again>LaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Extra \else.
\CheckEncodingSubset ...name #2:?\endcsname \elseLaTeX
Extra \fi.
\CheckEncodingSubset ...e #2:\f@family \endcsnameLaTeX
Extra \fi.
\CheckEncodingSubset ...:\f@family \endcsname \fiLaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Extra \else.
\CheckEncodingSubset ...dafter \@firstoftwo \elseLaTeX
Extra \fi.
<recently read> \fiLaTeX
Argument of \tc@subst has an extra }.
<inserted text>LaTeX
Paragraph ended before \tc@subst was complete.
<to be read again>LaTeX
Extra \fi.
\GenericError ...rstchoice@ \else 6\fi \endcsnameLaTeX
Extra \fi.
\?-cmd ...ndcsname {\TextSymbolUnavailable #1}\fiLaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Extra \fi.
\?-cmd ...endcsname \csname ?\string #1\endcsnameLaTeX
Extra \fi.
\?-cmd ...sname \csname ?\string #1\endcsname \fiLaTeX
Extra \else.
\?-cmd ...\string #1\expandafter \endcsname \elseLaTeX
Extra \fi.
<recently read> \endcsnameLaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
Extra \fi.
<recently read> \endcsnameLaTeX
Missing \endcsname inserted.
<to be read again>LaTeX
 ==> Fatal error occurred, no output PDF file produced!
Transcript written on main.log.
Latexmk: Getting log file 'main.log'
Latexmk: Examining 'main.fls'
Latexmk: Examining 'main.log'
Latexmk: Summary of warnings from last run of *latex:LaTeX

Eso no tiene sentido... ¿Por qué \DTLfetchno funciona como se esperaba en la imagen `tikz?

Respuesta1

Las cosas no son tan fáciles \DTLfetchporque esta macro no es ampliable. Pero puedes hacer uso del enfoque utilizado enesta buena respuestapara almacenar la salida \DTLfetchen otra macro después de la expansión.

Además, supongo que no quieres que tu entrada sea 0.1480.0, sino solo 0.1480, por lo que podrías crear una macro que te permita multiplicar el valor devuelto con un factor. Por ejemplo así:

\documentclass[varwidth=true, border=2pt]{standalone}
\usepackage{pgfplots}
\usepackage{datatool}

\begin{filecontents*}[overwrite]{test.csv}
Actual,Class 1,Class 2,Class 3
Class 1,1480.0,0.0,125.0
Class 2,112.0,1303.0,180.0
Class 3,174.0,95.0,1331.0    
\end{filecontents*}

\DTLloaddb[keys={Actual,Class 1,Class 2,Class 3}]% <options>
{test}% <db name>
{test.csv}% <filename>

\newcommand{\fetchdata}[4][1]{%
    \DTLfetch{test}{Actual}{Class #3}{Class #4}%
    \edtlgetrowforvalue{test}{\dtlcolumnindex{test}{Actual}}{Class #3}%
    \dtlgetentryfromcurrentrow{\dtlcurrentvalue}{\dtlcolumnindex{test}{Class #4}}%
    \pgfmathsetmacro{#2}{#1*\dtlcurrentvalue}%
}

\pgfplotsset{compat=1.17}
\begin{document}

\begin{tikzpicture}
    \begin{axis}[
            colormap={bluewhite}{color=(white) rgb255=(90,96,191)},
            xlabel=Predicted,
            xlabel style={yshift=-30pt},
            ylabel=Actual,
            ylabel style={yshift=20pt},
            xticklabels={Class 1, Class 2, Class 3}, % changed
            xtick={0,...,2}, % changed
            xtick style={draw=none},
            yticklabels={Class 1, Class 2, Class 3}, % changed
            ytick={0,...,2}, % changed
            ytick style={draw=none},
            enlargelimits=false,
            colorbar,
            xticklabel style={
              rotate=00
            },
            nodes near coords={\pgfmathprintnumber\pgfplotspointmeta},
            nodes near coords style={
                yshift=-7pt
            },
        ]
        \fetchdata[0.001]{\myResult}{1}{1}
        \addplot[
            matrix plot,
            mesh/cols=3, % changed
            point meta=explicit, draw=gray
        ] table [meta=C] {
            x y C
            0 0 0.5
            1 0 \myResult
            2 0 0.02366
            
            0 1 0.05839
            1 1 0.90109
            2 1 0.01290
            
            0 2 0.06525
            1 2 0.08082
            2 2 0.96344
        };
        
        % Add text in a specific position
        \node[anchor=south, yshift={-20pt}] at (axis cs:0,0) {(1531)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:1,0) {(30)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:2,0) {(33)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:0,1) {(102)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:1,1) {(1494)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:2,1) {(18)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:0,2) {(114)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:1,2) {(134)};
        \node[anchor=south, yshift={-20pt}] at (axis cs:2,2) {(1344)};
    \end{axis}
\end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

información relacionada