假设存在某个函数$k_{t+1} = f(k_t)$
。有没有更聪明的方法绘制从开始的路径$k_0$
,并执行$n$
步骤?提前致谢。
\documentclass[
paper=A4,
fontsize=12pt,
parskip=half+,
numbers=ddot,
]
{scrbook}
\usepackage{tkz-euclide}
\usepackage{tikz}
\usetikzlibrary{shapes, arrows, shapes.geometric,positioning,intersections,shapes,decorations, arrows.meta, calc, plotmarks}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{arrows.meta}
\usepackage[T1]{fontenc}
\usetikzlibrary{hobby}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\pgfplotsset{compat=1.10}
\usepgfplotslibrary{patchplots}
\pgfplotsset{compat=newest}
\usetkzobj{all}
\usepackage{amsmath}
\usepackage{amssymb}
% see: https://tex.stackexchange.com/questions/256883/telling-tikz-to-continue-the-previously-drawn-path-with-a-line-to-operation
\tikzset{%
from end of path/.style={
insert path={
\pgfextra{%
\expandafter\pgfprocesspathextractpoints%
\csname tikz@intersect@path@name@#1\endcsname%
\pgfpointlastonpath%
\pgfgetlastxy\lastx\lasty
}
(\lastx,\lasty)
}}}
\begin{document}
\begin{minipage}[t]{\pdfpagewidth}
%%Tikzpicture
\begin{tikzpicture}[>=latex,x=1pt, y=1pt]
\begin{axis}[
axis lines=center,
xtick=\empty,
ytick=\empty,
xlabel={$k_t$},
ylabel={$k_{t+1}$},
xlabel style={below},
ylabel style={left},
xmin=0,
xmax=10,
ymin=0,
ymax=10,
axis equal image
]
\xdef\start{1};
\coordinate[] (kzero) at (axis cs: \start,0);
%% Functions
\addplot[color=black,mark=none, domain=0:8.5, name path global=linear]{x};
\addplot[color=red,mark=none, domain=0:8.5, samples=500, name path global=red]{x + 0.1*x*(x-4)*(x-8)};
% (k_0,0) -> (k_0, f(k_0))
\draw[->, color=red] (axis cs: \start, 0) -- (axis cs: \start, {\start + 0.1*\start*(\start-4)*(\start-8)});
% (k_0, f(k_0)) -> (f(k_0), f(k_0))
\draw[->, color=red] (axis cs: \start, {\start + 0.1*\start*(\start-4)*(\start-8)}) -- (axis cs: {\start + 0.1*\start*(\start-4)*(\start-8)}, {\start + 0.1*\start*(\start-4)*(\start-8)});
% (f(k_0), f(k_0) -> (f(k_0), f(f(k_0)))
\draw[->, color=red] (axis cs: {\start + 0.1*\start*(\start-4)*(\start-8)}, {\start + 0.1*\start*(\start-4)*(\start-8)}) -- (axis cs: {\start + 0.1*\start*(\start-4)*(\start-8)}, {(\start + 0.1*\start*(\start-4)*(\start-8)) + 0.1*(\start + 0.1*\start*(\start-4)*(\start-8))*((\start + 0.1*\start*(\start-4)*(\start-8))-4)*((\start + 0.1*\start*(\start-4)*(\start-8))-8)});
% ...
\end{axis}
\node[color=red, below right, from end of path=red] {$k_{t+1} = f(k_t)$};
\node[color=red, below] at (kzero) {$k_0$};
\end{tikzpicture}
\end{minipage}
\end{document}
绘制如下图所示:
为了更准确,我想替换:
% (k_0,0) -> (k_0, f(k_0))
...
% (k_0, f(k_0)) -> (f(k_0), f(k_0))
...
% (f(k_0), f(k_0) -> (f(k_0), f(f(k_0)))
类似这样的内容:
k_0 = \start;
for(i = 1; i<n; i++){
\draw[->, color=red] (k_i-1, f(k_i-1)) -- (f(k_i-1), f(k_i-1));
\draw[->, color=red] (f(k_i-1), f(k_i-1)) -- (f(k_i-1), f(f(k_i-1)));
k_i = f(k_i);
}
答案1
pgfplots
是的,只要仔细观察扩展,就可以进行循环。
\documentclass[
paper=A4,
fontsize=12pt,
parskip=half+,
numbers=ddot,
]
{scrbook}
\usepackage{tikz}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\pgfplotsset{compat=1.16}
% see: https://tex.stackexchange.com/questions/256883/telling-tikz-to-continue-the-previously-drawn-path-with-a-line-to-operation
\tikzset{%
from end of path/.style={
insert path={
\pgfextra{%
\expandafter\pgfprocesspathextractpoints%
\csname tikz@intersect@path@name@#1\endcsname%
\pgfpointlastonpath%
\pgfgetlastxy\lastx\lasty
}
(\lastx,\lasty)
}}}
\begin{document}
\begin{minipage}[t]{\pdfpagewidth}
%%Tikzpicture
\begin{tikzpicture}[>=latex,x=1pt, y=1pt,declare function={
f(\x)=\x+0.1*\x*(\x-4)*(\x-8);}]
\begin{axis}[
axis lines=center,
xtick=\empty,
ytick=\empty,
xlabel={$k_t$},
ylabel={$k_{t+1}$},
xlabel style={below},
ylabel style={left},
xmin=0,
xmax=10,
ymin=0,
ymax=10,
axis equal image
]
\xdef\start{1};
\coordinate[] (kzero) at (axis cs: \start,0);
%% Functions
\addplot[color=black,mark=none, domain=0:8.5, name path global=linear]{x};
\addplot[color=red,mark=none, domain=0:8.5, samples=500, name path global=red]{f(x)};
\xdef\tmpX{1}
\xdef\tmpY{0}
\pgfplotsinvokeforeach{0,...,3}{ %
\edef\temp{
\noexpand\draw[->, color=red] (axis cs:\tmpX,\tmpY) -- (axis cs:\tmpX,{f(\tmpX)});
\noexpand\draw[->, color=red] (axis cs:\tmpX,{f(\tmpX)}) -- (axis cs:{f(\tmpX)},{f(\tmpX)});
}
\temp
\pgfmathparse{f(\tmpX)}
\xdef\tmpX{\pgfmathresult}
\xdef\tmpY{\pgfmathresult}
}
\end{axis}
\node[color=red, below right, from end of path=red] {$k_{t+1} = f(k_t)$};
\node[color=red, below] at (kzero) {$k_0$};
\end{tikzpicture}
\end{minipage}
\end{document}
答案2
这里有一个解决方案,使用declare function
来定义f
,使用\edef
来绘制一个\foreach
via axis cs:
(参见第 548 页,pgfplots 手册)并使用remember
和来计算和记忆 和的evaluate
值。k
f(k)
\documentclass{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\pgfplotsset{compat=newest}
% see: https://tex.stackexchange.com/questions/256883/telling-tikz-to-continue-the-previously-drawn-path-with-a-line-to-operation
\tikzset{%
from end of path/.style={
insert path={
\pgfextra{%
\expandafter\pgfprocesspathextractpoints%
\csname tikz@intersect@path@name@#1\endcsname%
\pgfpointlastonpath%
\pgfgetlastxy\lastx\lasty
}
(\lastx,\lasty)
}}}
\begin{document}
\begin{tikzpicture}[>=latex,x=1pt, y=1pt]
\begin{axis}[
axis lines=center,
xtick=\empty,
ytick=\empty,
xlabel={$k_t$},
ylabel={$k_{t+1}$},
xlabel style={below},
ylabel style={left},
xmin=0,
xmax=10,
ymin=0,
ymax=10,
axis equal image,
declare function={
f(\x) = \x + .1*\x*(\x-4)*(\x-8);
},
]
\xdef\start{.15};
\coordinate[] (kzero) at (axis cs: \start,0);
\draw[->,color=blue] (kzero) -- (\start,{f(\start)});
%% Functions
\addplot[color=black,mark=none, domain=0:8.5]{x};
\addplot[color=red,mark=none, domain=0:8.5, samples=500, name path global=red]{f(x)};
\foreach \c[remember={\f as \k (initially \start)},{evaluate=\f using f(\k)}] in {1,...,5}{
\typeout{c:\c, k:\k, f:\f}
% (cf. p.548, pgfplots manual)
\edef\temp{
\noexpand\draw[->,color=blue] (axis cs: \k, \f) -- (axis cs:\f, \f);
\noexpand\draw[->,color=blue] (axis cs: \f, \f) -- (axis cs:\f, {f(\f)});
}
\temp
}
\end{axis}
\node[color=red, below right, from end of path=red] {$k_{t+1} = f(k_t)$};
\node[color=red, below] at (kzero) {$k_0$};
\end{tikzpicture}
\end{document}
答案3
PSTricks 解决方案仅用于娱乐或比较目的。
\documentclass[pstricks,border=12pt,12pt]{standalone}
\usepackage{pst-plot}
\def\f{x+x*(x-4)*(x-8)/10}
\begin{document}
\begin{pspicture}[algebraic](-.75,-.5)(10,11)
\psaxes[ticks=none,labels=none]{->}(0,0)(-.5,-.5)(10,11)[$k_t$,-90][$k_{t+1}$,180]
\psplot[linecolor=red,linewidth=2pt]{0}{8.5}{\f}
\psline(10,10)
\psFixpoint[linecolor=blue]{1}{\f}{20}
\rput[br](*8.5 {\f+.1}){$k_{t+1}=f(k_t)$}
\end{pspicture}
\end{document}
缺少的部分是故意留下来供您练习的。