pgfplots 中的 For 循环无法正常运行

pgfplots 中的 For 循环无法正常运行

在这张图片中,我试图通过循环来完成虚线图(我设法在没有循环的情况下完成了此操作):

在此处输入图片描述

代码:

\documentclass[12pt]{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows}
\usepackage{changepage}
\usepackage[margin=1in]{geometry} 
\usepackage{float}
\usepgfplotslibrary{fillbetween}
\usetikzlibrary{decorations.markings}
\tikzset{arrow marks/.style={postaction=decorate,decoration={markings,
            mark=between positions #1 and 1 step #1 with {\arrow{>}}}},
    arrow marks/.default=10pt}
\begin{document}
    \begin{figure}[H]
        \begin{adjustwidth}{-0.7in}{-0.7in}
            \centering
            \begin{tikzpicture}
            \def\a{0.5}
            \def\lambda{5}

            \begin{axis}[
            axis on top, %so that axes won't get covered up by color
            %xtick distance = {1},
            %ytick distance = {1},
            xmin=-12,xmax=12,
            ymin=-8,ymax=8,
            height = 7in,width=1.2\textwidth,
            axis lines=center,
            axis line style=->, xlabel = {$x_1$}, ylabel={$x_2$},
            %axis equal,
            legend cell align = {left},
            every axis x label/.style={at={(ticklabel* cs:1.05)}, anchor=west,},
            every axis y label/.style={at={(ticklabel* cs:1.05)}, anchor=south,}, 
            title= {Bang-off-bang Control Trajectories},         title style={xshift=0, yshift=2em},
            domain=-15:15,samples=300,legend pos=outer north east]
            %Final Switch Curve x_2 < 0
            \addplot[->,>=latex,arrow marks=1cm,color = blue, thick, domain = -8:0,tips=proper]({-ln(1-\a*x)/\a^2 - x/\a}, {x}) node[below left, pos = 0.3, font = \small] {\(u^* = 1\)};


            %Final Switch Curve x_2 > 0
            \addplot[->,>=latex,arrow marks=1cm,color = red, thick, domain = 8:0,tips=proper]({ln(1+\a*x)/\a^2 - x/\a}, {x}) node[above right, pos = 0.3, font = \small] {\(u^* = -1\)};

            %Off Curve x_2 > 0
            \addplot[dotted, color = black, thick, domain = 8:0,tips=proper]({ln(1+(\lambda*\a*x)/(\lambda + 2*\a*x))/\a^2 - x/\a}, {x}) node[below left, pos = 0.25, font = \small] {\(u^* = 0\)};

            %Off curve x_2 < 0
            \addplot[dotted, color = black, thick, domain = -8:0,tips=proper]({-ln(1-(\lambda*\a*x)/(\lambda - 2*\a*x))/\a^2 - x/\a}, {x}) node[above right, pos = 0.25, font = \small] {\(u^* = 0\)};

            \foreach \p in {1.5, 1.75, 2, 2.5, 4}
                %Definitions
                \def\xTwoInitPosToZero{\p}
                \def\xOneInitPosToZero{ln(1 +(\lambda*\a* \xTwoInitPosToZero)/(\lambda + 2*\a*\xTwoInitPosToZero))/(\a^2) - \xTwoInitPosToZero/\a}
                \def\zeroControlPosToNeg{ln((2*\a* \xTwoInitPosToZero + \lambda)/\lambda)/\a}
                \def\xTwoInitNegToZero{-\xTwoInitPosToZero}
                \def\xOneInitNegToZero{-ln(1 -(\lambda*\a* \xTwoInitNegToZero)/(\lambda - 2*\a*\xTwoInitNegToZero))/(\a^2) - \xTwoInitNegToZero/\a}
                \def\zeroControlNegToPos{ln((-2*\a* \xTwoInitNegToZero + \lambda)/\lambda)/\a}
                %Pos
                \addplot[->,>=latex,arrow marks=1cm, tips = proper,
                color=red, dashed,thick,domain=-6:0] 
                ({x/\a + (\xTwoInitPosToZero/\a - 1/(\a^2))*(1 - exp(-\a*x)) + \xOneInitPosToZero}, {1/\a + (\xTwoInitPosToZero - 1/\a)*exp(-\a*x)});
                \addplot[->,>=latex, color=red, tips = proper, dashed,thick,domain=0:\zeroControlPosToNeg] ({(\xTwoInitPosToZero/\a)*(1 - exp(-\a*x)) + \xOneInitPosToZero}, {\xTwoInitPosToZero*exp(-\a*x)});
                %Neg
                \addplot[->,>=latex,arrow marks=1cm, tips = proper,
                color=blue, dashed,thick,domain=-6:0] 
                ({-x/\a + (\xTwoInitNegToZero/\a + 1/(\a^2))*(1 - exp(-\a*x)) + \xOneInitNegToZero}, {-1/\a + (\xTwoInitNegToZero + 1/\a)*exp(-\a*x)});
                \addplot[->,>=latex, color=blue, tips = proper, dashed,thick,domain=0:\zeroControlNegToPos] ({(\xTwoInitNegToZero/\a)*(1 - exp(-\a*x)) + \xOneInitNegToZero}, {\xTwoInitNegToZero*exp(-\a*x)});
            }
            \end{axis}
            \end{tikzpicture}
        \end{adjustwidth}
    \end{figure}
\end{document}

但是,我收到了许多错误之一(这里有一个): Undefined control sequence. ...osToZero}, {\xTwoInitPosToZero*exp(-\a*x)});

我甚至尝试了该\invokepgfplotsforeach命令,但代码还是无限期地运行。如何解决这个问题?(我见过的其他查询对它们有效,但这个查询不能正常工作)。

答案1

我很乐意删除它,但我无法在评论中写出它。除了明显的缺失之外,{pgfplots 中的循环还有一个微妙之处。这些内容在 pgfplots 手册 v1.17 第 545 页的顶部有描述。基本上,您需要确保图表得到完全展开的宏。我在那里重复了这个方法。

\documentclass[12pt]{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\usepackage{changepage}
\usepackage[margin=1in]{geometry} 
\usepackage{float}
\usepgfplotslibrary{fillbetween}
\usetikzlibrary{decorations.markings}
\tikzset{arrow marks/.style={postaction=decorate,decoration={markings,
            mark=between positions #1 and 1 step #1 with {\arrow{>}}}},
    arrow marks/.default=10pt}
\begin{document}
    \begin{figure}[H]
        \begin{adjustwidth}{-0.7in}{-0.7in}
            \centering
            \begin{tikzpicture}[declare function={a=0.5;lambda=5;}]

            \begin{axis}[
            axis on top, %so that axes won't get covered up by color
            %xtick distance = {1},
            %ytick distance = {1},
            xmin=-12,xmax=12,
            ymin=-8,ymax=8,
            height = 7in,width=1.2\textwidth,
            axis lines=center,
            axis line style=->, xlabel = {$x_1$}, ylabel={$x_2$},
            %axis equal,
            legend cell align = {left},
            every axis x label/.style={at={(ticklabel* cs:1.05)}, anchor=west,},
            every axis y label/.style={at={(ticklabel* cs:1.05)}, anchor=south,}, 
            title= {Bang-off-bang Control Trajectories},         title style={xshift=0, yshift=2em},
            domain=-15:15,samples=300,legend pos=outer north east]
            %Final Switch Curve x_2 < 0
            \addplot[->,>=latex,arrow marks=1cm,color = blue, thick, domain = -8:0,tips=proper]({-ln(1-a*x)/a^2 - x/a}, {x}) node[below left, pos = 0.3, font = \small] {\(u^* = 1\)};


            %Final Switch Curve x_2 > 0
            \addplot[->,>=latex,arrow marks=1cm,color = red, thick, domain = 8:0,tips=proper]({ln(1+a*x)/a^2 - x/a}, {x}) node[above right, pos = 0.3, font = \small] {\(u^* = -1\)};

            %Off Curve x_2 > 0
            \addplot[dotted, color = black, thick, domain = 8:0,tips=proper]({ln(1+(lambda*a*x)/(lambda + 2*a*x))/a^2 - x/a}, {x}) node[below left, pos = 0.25, font = \small] {\(u^* = 0\)};

            %Off curve x_2 < 0
            \addplot[dotted, color = black, thick, domain = -8:0,tips=proper]({-ln(1-(lambda*a*x)/(lambda - 2*a*x))/a^2 - x/a}, {x}) node[above right, pos = 0.25, font = \small] {\(u^* = 0\)};

            \foreach \p in {1.5, 1.75, 2, 2.5, 4}
                %Definitions
                {\pgfmathsetmacro\xTwoInitPosToZero{\p}
                \pgfmathsetmacro\xOneInitPosToZero{ln(1 +(lambda*a* \xTwoInitPosToZero)/(lambda + 2*a*\xTwoInitPosToZero))/(a^2) - \xTwoInitPosToZero/a}
                \pgfmathsetmacro\zeroControlPosToNeg{ln((2*a* \xTwoInitPosToZero + lambda)/lambda)/a}
                \pgfmathsetmacro\xTwoInitNegToZero{-\xTwoInitPosToZero}
                \pgfmathsetmacro\xOneInitNegToZero{-ln(1 -(lambda*a* \xTwoInitNegToZero)/(lambda - 2*a*\xTwoInitNegToZero))/(a^2) - \xTwoInitNegToZero/a}
                \pgfmathsetmacro\zeroControlNegToPos{ln((-2*a* \xTwoInitNegToZero + lambda)/lambda)/a}
                %Pos
                \edef\temp{\noexpand\addplot[->,>=latex,arrow marks=1cm, tips = proper,
                color=red, dashed,thick,domain=-6:0] 
                ({x/a + (\xTwoInitPosToZero/a - 1/(a^2))*(1 - exp(-a*x)) + \xOneInitPosToZero}, {1/a + (\xTwoInitPosToZero - 1/a)*exp(-a*x)});
                \noexpand\addplot[->,>=latex, color=red, tips = proper, dashed,thick,domain=0:\zeroControlPosToNeg] ({(\xTwoInitPosToZero/a)*(1 - exp(-a*x)) + \xOneInitPosToZero}, {\xTwoInitPosToZero*exp(-a*x)});
                %Neg
                \noexpand\addplot[->,>=latex,arrow marks=1cm, tips = proper,
                color=blue, dashed,thick,domain=-6:0] 
                ({-x/a + (\xTwoInitNegToZero/a + 1/(a^2))*(1 - exp(-a*x)) + \xOneInitNegToZero}, {-1/a + (\xTwoInitNegToZero + 1/a)*exp(-a*x)});
                \noexpand\addplot[->,>=latex, color=blue, tips = proper,
                dashed,thick,domain=0:\zeroControlNegToPos]
                ({(\xTwoInitNegToZero/a)*(1 - exp(-a*x)) +
                \xOneInitNegToZero},
                {\xTwoInitNegToZero*exp(-a*x)});}
                \temp
            }
            \end{axis}
            \end{tikzpicture}
        \end{adjustwidth}
    \end{figure}
\end{document}

在此处输入图片描述

另外还有两个题外的变化:

  1. 几个\defs 被替换为\pgfmathsetmacros。这在某种程度上是有好处的,因为 LaTeX 在绘图中进行计算时不必经常计算这些表达式。
  2. \lambda被“函数” 取代lambda, 也是如此a。虽然使用宏完全没问题,但可能不想覆盖标准 LaTeX 命令,如\lambda。虽然这些更改只是局部的,但您失去了排版的能力\lambda(无需进一步努力),从长远来看,这种做法几乎肯定会造成不必要的麻烦。

相关内容