如果您能帮助我解决 Tikz 中的一个问题,我将非常高兴。我想为一篇关于流行病学系统的论文绘制一个图表(如下图所示),有两个问题(更重要的一个与箭头有关)。
我想在图表上画 3 个指向左侧的箭头来显示运动(基本上从 S = 1 开始)。我尝试根据这个答案来实现这一点(为平滑的 tikz 函数添加箭头),但是我无法获得3支箭,而且我不知道如何改变方向。
我需要大量样本(2000)才能完整绘制图表。如果我使用较少的样本,图表就会停止。您知道如何改进吗?
感谢您的支持。
\documentclass[tikz,border=2mm]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{arrows.meta,positioning}
\usetikzlibrary{decorations.markings}
\tikzset{
set arrow inside/.code={\pgfqkeys{/tikz/arrow inside}{#1}},
set arrow inside={end/.initial=>, opt/.initial=},
/pgf/decoration/Mark/.style={
mark/.expanded=at position #1 with
{
\noexpand\arrow[\pgfkeysvalueof{/tikz/arrow inside/opt}]{\pgfkeysvalueof{/tikz/arrow inside/end}}
}
},
arrow inside/.style 2 args={
set arrow inside={#1},
post*emphasized text*action={
decorate,decoration={
markings,Mark/.list={#2}
}
}
},
}
\begin{document}
\begin{tikzpicture}[>=latex]
\begin{axis}[
axis x line=center,
axis y line=center,
xmin=0, xmax=1.1,
ymin=0, ymax=1.1,
xtick={0,1},
ytick={0,1},
hide obscured x ticks=false,
extra x ticks={0.33},
extra x tick labels={$\frac{\gamma}{\beta}$},
extra y ticks={0.3},
extra y tick labels={$I_{\text{max}}$},
xlabel=$S$, ylabel=$I$,
xlabel style={right},
ylabel style={above},
scale=1.2
]
\draw[dashed] (axis cs: 0.33,1) -- (axis cs: 0.33,0) node[pos=1, below] {$\frac{\gamma}{\beta}$};
\draw[dashed] (axis cs: 0,0.3) -- (axis cs: 1,0.3);
\addplot[smooth] {1-x};
\addplot[samples=2000, red, smooth] {1 + (1/3) * ln(x) - x} [arrow inside={end=stealth,opt={red,scale=2}}{0.25,0.50.75}];
%\addplot[samples=1500, green, smooth] {1 + (1/6) * ln(x) - x} [arrow inside={end=stealth,opt={green,scale=1.5}}{0.25,0.50.75}];
\node[label={45:{$(S^*,I_{\text{max}})$}}, circle, fill, inner sep=1pt] at (axis cs: 0.33,0.3) {};
\end{axis}
\end{tikzpicture}
\end{document}
答案1
欢迎!对于 2,我添加了一个域以避免取负数或零的对数的无效点,并且对于 1,修复了箭头位置。不幸的是,平滑图decorations.markings
很容易产生dimension too large
错误,因此必须删除smooth
,但考虑到样本数量仍然相当多,结果看起来仍然很好,几乎与平滑版本没有区别。
\documentclass[tikz,border=2mm]{standalone}
\usepackage{amsmath}
\usepackage{pgfplots}
\pgfplotsset{compat=1.17}
\usetikzlibrary{arrows.meta,positioning}
\usetikzlibrary{decorations.markings}
\tikzset{
set arrow inside/.code={\pgfqkeys{/tikz/arrow inside}{#1}},
set arrow inside={end/.initial=>, opt/.initial=},
/pgf/decoration/Mark/.style={
mark/.expanded=at position #1 with
{
\noexpand\arrow[\pgfkeysvalueof{/tikz/arrow inside/opt}]{\pgfkeysvalueof{/tikz/arrow inside/end}}
}
},
arrow inside/.style 2 args={
set arrow inside={#1},
postaction={
decorate,decoration={
markings,Mark/.list={#2}
}
}
},
}
\begin{document}
\begin{tikzpicture}[>=latex]
\begin{axis}[
axis x line=center,
axis y line=center,
xmin=0, xmax=1.1,
ymin=0, ymax=1.1,
xtick={0,1},
ytick={0,1},
hide obscured x ticks=false,
extra x ticks={0.33},
extra x tick labels={$\frac{\gamma}{\beta}$},
extra y ticks={0.3},
extra y tick labels={$I_{\text{max}}$},
xlabel=$S$, ylabel=$I$,
xlabel style={right},
ylabel style={above},
scale=1.2
]
\draw[dashed] (axis cs: 0.33,1) -- (axis cs: 0.33,0) node[pos=1, below] {$\frac{\gamma}{\beta}$};
\draw[dashed] (axis cs: 0,0.3) -- (axis cs: 1,0.3);
\addplot[smooth] {1-x};
\addplot[samples=101, red,domain=0.05:1,
arrow inside={end=stealth,opt={red,scale=2}}{0.25,0.5,0.75}]
{1 + (1/3) * ln(x) - x}
;
\addplot[samples=101, green!70!black, domain=0.002:1,
arrow inside={end=stealth,opt={green!70!black,scale=1.5}}{0.25,0.5,0.75}] {1 + (1/6) * ln(x) - x} ;
\node[label={45:{$(S^*,I_{\text{max}})$}}, circle, fill, inner sep=1pt]
at (axis cs: 0.33,0.3) {};
\end{axis}
\end{tikzpicture}
\end{document}
可以避免dimension too large
告诉 Ti钾Z 用于fpu
计算倒数。
\documentclass[tikz,border=2mm]{standalone}
\usepackage{amsmath}
\usepackage{pgfplots}
\pgfplotsset{compat=1.17}
\usetikzlibrary{arrows.meta,positioning}
\usetikzlibrary{decorations.markings}
\tikzset{
set arrow inside/.code={\pgfqkeys{/tikz/arrow inside}{#1}},
set arrow inside={end/.initial=>, opt/.initial=},
/pgf/decoration/Mark/.style={
mark/.expanded=at position #1 with
{
\noexpand\arrow[\pgfkeysvalueof{/tikz/arrow inside/opt}]{\pgfkeysvalueof{/tikz/arrow inside/end}}
}
},
arrow inside/.style 2 args={
set arrow inside={#1},
postaction={
decorate,decoration={
markings,Mark/.list={#2}
}
}
},
}
\makeatletter
\tikzset{use fpu reciprocal/.code={%
\def\pgfmathreciprocal@##1{%
\begingroup
\pgfkeys{/pgf/fpu=true,/pgf/fpu/output format=fixed}%
\pgfmathparse{1/##1}%
\pgfmath@smuggleone\pgfmathresult
\endgroup
}}}%
\makeatother
\begin{document}
\begin{tikzpicture}[>=latex]
\begin{axis}[
axis x line=center,
axis y line=center,
xmin=0, xmax=1.1,
ymin=0, ymax=1.1,
xtick={0,1},
ytick={0,1},
hide obscured x ticks=false,
extra x ticks={0.33},
extra x tick labels={$\frac{\gamma}{\beta}$},
extra y ticks={0.3},
extra y tick labels={$I_{\text{max}}$},
xlabel=$S$, ylabel=$I$,
xlabel style={right},
ylabel style={above},
scale=1.2
]
\draw[dashed] (axis cs: 0.33,1) -- (axis cs: 0.33,0) node[pos=1, below] {$\frac{\gamma}{\beta}$};
\draw[dashed] (axis cs: 0,0.3) -- (axis cs: 1,0.3);
\addplot[smooth] {1-x};
\begin{scope}[use fpu reciprocal,>=stealth]
\addplot[samples=101, red,domain=0.05:1,smooth,
arrow inside={end={<},opt={red,scale=2}}{0.25,0.5,0.75}]
{1 + (1/3) * ln(x) - x}
;
\addplot[samples=101, green!70!black, domain=0.002:1,smooth,
arrow inside={end={<},opt={green!70!black,scale=1.5}}{0.25,0.5,0.75}] {1 + (1/6) * ln(x) - x} ;
\end{scope}
\node[label={45:{$(S^*,I_{\text{max}})$}}, circle, fill, inner sep=1pt]
at (axis cs: 0.33,0.3) {};
\end{axis}
\end{tikzpicture}
\end{document}