pgfplots中@for循环变量始终为列表首个值的问题咨询
问题成因
这个问题的核心是pgfplots的延迟展开机制与LaTeX循环变量的作用域特性共同导致的:
- pgfplots处理
\nextgroupplot的轴标签、样式等配置项时,不会立刻展开其中的宏变量,而是会将配置内容暂存,等到所有绘图指令执行完成、最终渲染输出时才统一展开宏生成标签内容。 - 你使用的
\@for循环的变量默认是局部作用域,每轮循环的赋值仅在当前循环体内部生效,等到渲染阶段实际执行标签宏展开时,循环早已执行完毕,变量已被重置为初始值,因此所有标签解析时拿到的都是第一个值1。如果使用全局赋值的循环实现,还可能出现所有标签都显示最后一个值的情况,本质都是循环变量值没有被固化到标签配置里。
解决方法
推荐直接使用pgfplots原生提供的\pgfplotsinvokeforeach循环命令,该命令专门适配pgfplots的延迟展开机制,会在每轮循环执行时就立刻把当前的循环变量值固化到后续的绘图指令中,不会出现变量值被后续循环覆盖的问题。
修改后的可运行代码如下:
\documentclass[a4paper, 11pt]{article} \usepackage{pgfplots} \pgfplotsset{compat=1.13} \usepgfplotslibrary{groupplots} \begin{document} \begin{tikzpicture} \begin{groupplot}[group style={group size= 2 by 3}] \pgfplotsinvokeforeach{1,2,3}{% \nextgroupplot[ylabel={$h = \frac{1}{#1}$}] \addplot {exp(x)}; \nextgroupplot \addplot{2 * x}; } \end{groupplot} \end{tikzpicture} \end{document}
如果要保留使用\@for的写法,也可以通过手动展开当前循环变量的方式实现,在循环内添加临时变量固化当前\refin的取值即可:
\makeatletter \begin{tikzpicture} \begin{groupplot}[group style={group size= 2 by 3}] \@for\refin:={1,2,3}\do{% \edef\temp{\noexpand\nextgroupplot[ylabel={$h = \frac{1}{\refin}$}]} \temp \addplot {exp(x)}; \nextgroupplot \addplot{2 * x}; } \end{groupplot} \end{tikzpicture} \makeatother
内容的提问来源于stack exchange,提问作者SteP
相关产品推荐
相关产品推荐

