Стрелки на графике функции с Tikz

Стрелки на графике функции с Tikz

Я был бы рад, если бы вы помогли мне с проблемой в Tikz. Я хочу нарисовать диаграмму для статьи об эпидемиологических системах (как показано ниже) и у меня есть две проблемы (более важная из них касается стрелок).

  1. Я хочу нарисовать на графике 3 стрелки, которые указывают влево, чтобы показать движение (которое в основном начинается с S = 1). Я попытался реализовать это на основе этого ответа (Добавьте стрелки к плавной функции tikz), но я не могу получить 3 стрелки и понятия не имею, как изменить направление.

  2. Мне нужно много выборок (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ошибок и использовать гладкие графики, если сказать Тик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}

введите описание изображения здесь

Связанный контент