![通过filecontents和pgfplotstableread存储表格数据有什么区别?](https://linux22.com/image/386337/%E9%80%9A%E8%BF%87filecontents%E5%92%8Cpgfplotstableread%E5%AD%98%E5%82%A8%E8%A1%A8%E6%A0%BC%E6%95%B0%E6%8D%AE%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%9F.png)
在此 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 进行更复杂的注释。我想知道是否还有其他明显的用例。