在绘制和遍历文件名列表时,我想从 switch 代码中调用它们并将它们应用于。我使用了xstring 包中的\addplot
switch 函数。但是,文件名包含下划线,这导致编译错误,即下划线被解释为数学模式,即使它位于 的文件地址参数内。我想知道:\IfEqCase
Missing $ inserted
\addplot
如何从 switch-case(类似\IfEqCase
,但不一定是该函数)中将带有下划线的文件名调用到 addplot 参数中?
代码中要查找的位:\getFilename
调用\IfEqCase
并应用于绘图的新命令:\addplot table {\getFilename{\i}}
。
代码:
% !TeX program = lualatex
\documentclass[tikz,border=10pt]{standalone}
\usepackage{xstring}% for \IfEqCase
\usepackage{pgfplots}
\pgfplotsset{compat=1.17}
\newenvironment{standalonepage}{}{}
\standaloneenv{standalonepage}
\begin{filecontents}{file_1_someInfo.csv}
1,1
2,2
3,3
\end{filecontents}
\begin{filecontents}{file_2_someOtherInfo.csv}
1,4
2,5
3,6
\end{filecontents}
\newcommand{\getFilename}[1]{
\IfEqCase{#1}{
{1}{file_1_someInfo}
{2}{file_2_someOtherInfo}
}[\PackageError{filename}{Undefined option to filename of file #1}{}]
}
\begin{document}
\begin{standalonepage}
\begin{tikzpicture}
\begin{axis}
\foreach \i in {1,2}{
\addplot+ table [x index=0,y index=1,col sep=comma]
{\getFilename{\i}};
\edef\temp{\noexpand\addlegendentry{file no. \i};}
\temp
};
\end{axis}
\end{tikzpicture}
\end{standalonepage}
\end{document}
尝试修复,但失败了
我已经尝试过\catcode
(如建议每当带有下划线的文本被输入到新命令的参数中时)来改变代码的类别:
\newcommand{\getFilename}[1]{\begingroup
\catcode`_=12 \getthelist{#1}}
\newcommand{\getthelist}[1]{
\IfEqCase{#1}{%krever package xstring
{1}{file_1_someInfo}
{2}{file_2_someOtherInfo}
}[\PackageError{filename}{Undefined option to filename of file #1}{}]%
\endgroup
}
这会导致错误Missing $ inserted
。
问题似乎出在 \IfEqCase
,因为如果我定义命令,代码就可以工作(没有错误并且图形已绘制):
\newcommand{\getFilename}[1]{Folder_1_extraInfo}
但我无法遍历这些文件。
我也尝试\IfEqCase
直接申请\addplot
:
\begin{axis}
\foreach \i in {1,2}{
\addplot+ table [x index=0,y index=1,col sep=comma] {\IfEqCase{\i}{
{1}{file_1_someInfo}
{2}{file_2_someOtherInfo}
}[\PackageError{filename}{Undefined option to filename of file #1}{}]
};
\edef\temp{\noexpand\addlegendentry{file no. \i};}
\temp
};
\end{axis}
但导致了错误Illegal parameter number in definition of \pgffor@body.
答案1
常见的问题:\IfEqCase
返回打印结果的指令,而不是结果本身。
这是一个使用的可扩展版本expl3
。
\begin{filecontents}{file_1_someInfo.csv}
1,1
2,2
3,3
\end{filecontents}
\begin{filecontents}{file_2_someOtherInfo.csv}
1,4
2,5
3,6
\end{filecontents}
\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.17}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\getFilename}{m}
{
\str_case_e:nnF {#1}
{
{1}{file_1_someInfo}
{2}{file_2_someOtherInfo}
}
{\PackageError{filename}{Undefined~option~to~filename~of~file~#1}}
.csv
}
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture}
\begin{axis}
\foreach \i in {1,2}{
\addplot+ table [x index=0,y index=1,col sep=comma] {\getFilename{\i}};
\expanded{\noexpand\addlegendentry{file no. \i}}
}
\end{axis}
\end{tikzpicture}
\end{document}
我让你制作不覆盖数据的图例。
答案2
这是另一种解决方案functional
使用\prgRunTwoArgCode
命令进行打包。
\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.17}
\begin{filecontents*}[overwrite]{file_1_someInfo.csv}
1,1
2,2
3,3
\end{filecontents*}
\begin{filecontents*}[overwrite]{file_2_someOtherInfo.csv}
1,4
2,5
3,6
\end{filecontents*}
\usepackage{functional}
\IgnoreSpacesOn
\prgNewFunction \GetFileName {m} {
\strCaseF {#1} {
{1}{\prgReturn{file_1_someInfo}}
{2}{\prgReturn{file_2_someOtherInfo}}
}
{\PackageError{filename}{Undefined~option~to~filename~of~file~#1}}
}
\IgnoreSpacesOff
\begin{document}
\begin{tikzpicture}
\begin{axis}
\foreach \i in {1,2}{
\prgRunTwoArgCode {\GetFileName{\expWhole{\i}}} {\expWhole{\i}} {
\addplot+ table [x index=0,y index=1,col sep=comma] {##1.csv};
\addlegendentry{file no. ##2};
}
}
\end{axis}
\end{tikzpicture}
\end{document}