通过filecontents和pgfplotstableread存储表格数据有什么区别?

通过filecontents和pgfplotstableread存储表格数据有什么区别?

在此 MWE 中,已成功解析加载的表数据poles.dat,如左图所示。

但是,在宏中使用存储相同的数据\pgfplotstableread不会产生相同的预期输出。

为什么这两种方式有区别?以及如何使第二种方法pgfplotstableread像第一种方法一样工作*.dat

\documentclass[border=1cm]{standalone}

\usepackage{pgfplots,pgfplotstable}

\pgfplotsset{compat=newest,
    poles/.style= { only marks, mark=x, mark size = 1ex, thick},
    point meta = explicit symbolic,
    visualization depends on={\thisrow{angle} \as \myangle},
    visualization depends on={value \thisrow{label} \as \mylabel},
    Label Style/.style args = {#1}{
        nodes near coords,
        every node near coord/.style = %
        {
            anchor=south, label={[#1]\myangle:{\mylabel}}
        },
    }
}

\usepackage{filecontents}
\begin{filecontents*}{poles.dat}
    Re      Im      label       angle
    -2      2       (-2,2)      270
    -2      -2      (-2,-2)     90
    -4      0       (-4,0)      60
\end{filecontents*}

\pgfplotstableread{
    Re      Im      label       angle
    -2      2       (-2,2)      270
    -2      -2      (-2,-2)     90
    -4      0       (-4,0)      60
}\mytable

\begin{document} 
    \begin{tikzpicture}
    \begin{axis}
        \addplot[Label Style={blue,fill = gray!20},poles]   table {poles.dat};
    \end{axis}
    \end{tikzpicture}
    \begin{tikzpicture}
    \begin{axis}
        \addplot[Label Style={blue,fill = gray!20},poles]   table {\mytable};
    \end{axis}
    \end{tikzpicture}
\end{document}

在此处输入图片描述

答案1

我在 pgfplots 源代码中发现了以下内容。

% The normal implementation of \thisrow is not accessable here. And the
% worst is: error messages are impossible either because they are
% not executed... we resort to the associated math functions:
\def\thisrow##1{thisrow("##1")}% let us hope that math parsing is active!

请注意,此解决方案总是用途\mytable。关键是使用\coordindex

\documentclass[border=1cm]{standalone}

\usepackage{pgfplotstable,pgfplots}

\pgfplotsset{compat=newest,
    poles/.style= { only marks, mark=x, mark size = 1ex, thick},
    point meta = explicit symbolic,
    visualization depends on={\thisrow{angle} \as \myangle},
    %visualization depends on={value \thisrow{label} \as \mylabel},
    Label Style/.style args = {#1}{
        nodes near coords,
        every node near coord/.style = %
        {
            anchor=south, label={[#1]\myangle:{\pgfplotstablegetelem{\coordindex}{label}\of{\mytable}\pgfplotsretval}}
        },
    }
}
\newcommand{\myotherlabel}{\pgfmathparse{\thisrow{label}}\pgfmathresult}

\usepackage{filecontents}
\begin{filecontents*}{poles.dat}
    Re      Im      label       angle
    -2      2       (-2,2)      270
    -2      -2      (-2,-2)     90
    -4      0       (-4,0)      60
\end{filecontents*}

\pgfplotstableread[columns/label/.style={string}]{
    Re      Im      label       angle
    -2      2       (-2,2)      270
    -2      -2      (-2,-2)     90
    -4      0       (-4,0)      60
}\mytable

\begin{document} 
    \begin{tikzpicture}
    \begin{axis}
        \addplot[Label Style={blue,fill = gray!20},poles]   table {poles.dat};
    \end{axis}
    \end{tikzpicture}
    \begin{tikzpicture}
    \begin{axis}
        \addplot[Label Style={blue,fill = gray!20},poles]   table {\mytable};
    \end{axis}
    \end{tikzpicture}
\end{document}

答案2

这里有一个疯狂的解决方法:将表写入文件并再次读取。(当然,在本例中,这没有意义。)但是,在某些情况下,这是有意义的,例如当您通过宏创建表时,或者当您真的想要跳过一些行,例如这里

\documentclass[border=1cm]{standalone}

\usepackage{pgfplots,pgfplotstable}

\pgfplotsset{compat=newest,
    poles/.style= { only marks, mark=x, mark size = 1ex, thick},
    point meta = explicit symbolic,
    visualization depends on={\thisrow{angle} \as \myangle},
    visualization depends on={value \thisrow{label} \as \mylabel},
    Label Style/.style args = {#1}{
        nodes near coords,
        every node near coord/.style = %
        {
            anchor=south, label={[#1]\myangle:{\mylabel}}
        },
    }
}

% from https://tex.stackexchange.com/a/445369/121799
\newcommand*{\ReadOutElement}[4]{%
    \pgfplotstablegetelem{#2}{#3}\of{#1}%
    \let#4\pgfplotsretval
}
% based on https://tex.stackexchange.com/a/307032/121799
% and https://tex.stackexchange.com/a/451326/121799
\newcommand{\GetRow}[2]{
\pgfplotstablegetcolsof{\mytable}
\pgfmathtruncatemacro{\colnumber}{\pgfplotsretval-1}
\foreach \XX in {0,...,\colnumber}
{%
\ReadOutElement{\mytable}{#1}{[index]\XX}{\tmp}%
\ifnum\XX=0%
\xdef#2{{\tmp}}%
\else%
\xdef#2{#2,{\tmp}}%
\fi%
}
}

\usepackage{filecontents}
\begin{filecontents*}{poles.dat}
    Re      Im      label       angle
    -2      2       (-2,2)      270
    -2      -2      (-2,-2)     90
    -4      0       (-4,0)      60
\end{filecontents*}

\pgfplotstableread{
    Re      Im      label       angle
    -2      2       (-2,2)      270
    -2      -2      (-2,-2)     90
    -4      0       (-4,0)      60
}\mytable

\pgfplotstablegetrowsof{\mytable}%
\pgfmathtruncatemacro{\rownum}{\pgfplotsretval-1}%
\pgfplotstablegetcolsof{\mytable}%
\pgfmathtruncatemacro{\colnum}{\pgfplotsretval-1}%
\foreach \X in {0,...,\colnum}%
{\pgfplotstablegetcolumnnamebyindex{\X}\of{\mytable}\to\pgfplotsretval%
\ifnum\X=0%
\xdef\tmp{\pgfplotsretval}%
\else%
\xdef\tmp{\tmp,\pgfplotsretval}%
\fi}
\newwrite\myoutput% from https://tex.stackexchange.com/a/290058/121799
\immediate\openout\myoutput=\jobname-tmp.dat%
\immediate\write\myoutput{\tmp}% create table header
\foreach \X in {0,...,\rownum}% rows
{\GetRow{\X}{\myrow}%
\immediate\write\myoutput{\myrow}}%
\immediate\closeout\myoutput%

\begin{document} 
    \begin{tikzpicture}
    \begin{axis}
        \addplot[Label Style={blue,fill = gray!20},poles]   table {poles.dat};
    \end{axis}
    \end{tikzpicture}
    \begin{tikzpicture}
    \begin{axis}
        \addplot[Label Style={blue,fill = gray!20},poles]   
        table[col sep=comma] {\jobname-tmp.dat};
    \end{axis}
    \end{tikzpicture}
\end{document}

在此处输入图片描述

不用说,可以清理宏。在了解所有可能的应用之前,我犹豫着是否要这么做。一个是跳过行,这对于回归图很重要,另一个就像这里一样,人们使用 pgfplots 进行更复杂的注释。我想知道是否还有其他明显的用例。

相关内容