在这张图片中,我试图通过循环来完成虚线图(我设法在没有循环的情况下完成了此操作):
代码:
\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}
另外还有两个题外的变化:
- 几个
\def
s 被替换为\pgfmathsetmacro
s。这在某种程度上是有好处的,因为 LaTeX 在绘图中进行计算时不必经常计算这些表达式。 \lambda
被“函数” 取代lambda
, 也是如此a
。虽然使用宏完全没问题,但可能不想覆盖标准 LaTeX 命令,如\lambda
。虽然这些更改只是局部的,但您失去了排版的能力\lambda
(无需进一步努力),从长远来看,这种做法几乎肯定会造成不必要的麻烦。