A solution I often use to draw phase diagrams is this one from How to draw slope fields with all the possible solution curves in latex, which I added my version with two functions in quiver={ u={f(x,y)}, v={g(x,y)} ...}
.
It lets me generate local quivers from functions f(x,y)
and g(x,y)
while keeping a predefined style. I may add new curves with \addplot
such as \addplot +[blue] {-4*x};
, which seems to be one of the the lines, the one with \addplot +[violet] {+x}
I could visually find.
Improvements needed to achieve final result:
- Draw arrows correctly where I used
\addplot
to draw added functions.
- Draw arrows in quiver with curves.
- Automatically find equations for
\addplot
, as it is, one must do the math and then insert results.
\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\usepackage{amsmath}
\usepackage{derivative}
\pgfplotsset{ % Define a common style, so we don't repeat ourselves
MyQuiver2D/.style={
width=0.6\textwidth, % Overall width of the plot
axis equal image, % Unit vectors for both axes have the same length
view={0}{90}, % We need to use "3D" plots, but we set the view so we look at them from straight up
xmin=-2.1, xmax=2.1, % Axis limits
ymin=-2.1, ymax=2.1,
domain=-2:2, y domain=-2:2, % Domain over which to evaluate the functions
xtick={-2,-1.5,...,2}, ytick={-2,-1.5,...,2}, % Tick marks %
samples=21, % How many arrows?
cycle list={ % Plot styles
gray,
quiver={
u={f(x,y)}, v={g(x,y)}, % End points of the arrows
scale arrows=0.015,
every arrow/.append style={
-latex % Arrow tip
},
}\\
red, samples=31, smooth, very thick, no markers, domain=-2:2\\ % The plot style for the function
}
}
}
\begin{document}
\begin{tikzpicture}[
declare function={f(\x,\y) = \x - 4*\x*\x + 2*\y*\y + 10*\x*\y;},
declare function={g(\x,\y) = \y + 4*\y*\y + 4*\x*\y;}
]
\begin{axis}[
MyQuiver2D,
title={$\displaystyle \odv{x}{t}=x-4x^2+2y^2+10xy; \odv{y}{t}=y+4y^2+4xy$},
width=\textwidth
]
\addplot3 (x,y,0);
\addplot +[] {0};
\addplot3 (x,y,0);
\addplot +[magenta] {-4*x};
\addplot3 (x,y,0);
\addplot +[violet] {+x};
\end{axis}
\end{tikzpicture}
\end{document}
Edit and Update
This solution improves:
- All vector are normalized and colored quiver, where colors represent the "strength" or "real size".
- Each plot has decorations with arrows.
- Better organization of styles to reuse and default settings.
The solution is based on:
While editing your graph, I realized it could be interesting show the fixed points of your EDO, despite they are not shown in the original paper. In this process, I noted I created the first solution with domain=-2:2
, and I could not really see the vector field close to some fixed points. Therefore I added them with coordinates
. I checked the fixed points with WolframAlpha:
So I edited styles in order to better handles local defined domains and then I created a second figure with domain=-0.4:0.4
.
A MWE follows:
\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\usetikzlibrary{decorations.markings}
\usepackage{amsmath}
\usepackage{derivative}
% Define style to the axis
\pgfplotsset{MyQuiverAxis/.style={
width=\textwidth, % Overall width of the plot
xlabel={$x$}, ylabel={$y$},
xmin=-2.1, xmax=2.1, % Axis limits
ymin=-2.1, ymax=2.1,
domain=-2:2, y domain=-2:2, % Domain over which to evaluate the functions
axis equal image, % Unit vectors for both axes have the same length
view={0}{90}, % We need to use "3D" plots, but we set the view so we look at them from straight up
% colormap/viridis,
colormap/hot,
colorbar,
colorbar style = {
ylabel = {Vector Length}
}
}
}
% Define a common style to quivers
\pgfplotsset{MyQuiver2Dnorm/.style={
%cycle list={% Plot styles
samples=15, % How many arrows?
quiver={
u={f(x,y)/sqrt((f(x,y)^2+(g(x,y))^2))}, v={g(x,y)/sqrt((f(x,y)^2+(g(x,y))^2))}, % End points of the arrows
scale arrows=0.2,
},
-latex,
%},
% domain=-0.5:0.5, y domain=-0.5:0.5, % Change if domain not equal to axis functions
quiver/colored = {mapped color},
point meta = {sqrt((f(x,y))^2+(g(x,y))^2)},
}
}
\pgfplotsset{MyArrowDecorationPlot/.style n args={3}{
decoration={
markings,
mark=between positions #1 and #2 step 2em with {\arrow [scale=#3]{latex}}
}, postaction=decorate
},
MyArrowDecorationPlot/.default={0.1}{0.99}{1.5}
}
\begin{document}
\begin{tikzpicture}[
declare function={f(\x,\y) = \x - 4*(\x)^2 + 2*(\y)^2 + 10*\x*\y;},
declare function={g(\x,\y) = \y + 4*(\y)^2 + 4*\x*\y;}
]
\begin{axis}[
MyQuiverAxis,
title={$\displaystyle \odv{x}{t} = x-4x^2+2y^2+10xy; \odv{y}{t} = y+4y^2+4xy$},
]
\addplot3 [MyQuiver2Dnorm] (x,y,0);
\addplot [thick, red, domain=2:-2, MyArrowDecorationPlot] {0};
\addplot [thick, magenta, domain=2:-2, MyArrowDecorationPlot] {-4*x};
\addplot [thick, violet, MyArrowDecorationPlot] {+x};
\addplot [very thick, fill=white, only marks] coordinates {(0,0) (-1/8,-1/8) (1/12,-1/3) (1/4,0)};
\end{axis}
\end{tikzpicture}
\begin{tikzpicture}[
declare function={f(\x,\y) = \x - 4*\x*\x + 2*\y*\y + 10*\x*\y;},
declare function={g(\x,\y) = \y + 4*\y*\y + 4*\x*\y;}
]
\begin{axis}[
MyQuiverAxis,
title={$\displaystyle \odv{x}{t} = x-4x^2+2y^2+10xy; \odv{y}{t} = y+4y^2+4xy$},
xmin=-0.4, xmax=0.4, % Axis limits
ymin=-0.4, ymax=0.4,
domain=-0.4:0.4, y domain=-0.4:0.4
]
\addplot3 [MyQuiver2Dnorm,
domain=-0.35:0.35, y domain=-0.35:0.35,
quiver={scale arrows=0.025}] (x,y,0);
\addplot [thick, red, domain=0:-0.4, MyArrowDecorationPlot] {0};
\addplot [thick, red, domain=0:1/4, MyArrowDecorationPlot] {0};
\addplot [thick, red, domain=0.4:1/4, MyArrowDecorationPlot] {0};
\addplot [thick, magenta, domain=0:-0.4,
MyArrowDecorationPlot={0.05}{1}{1.25}] {-4*x};
\addplot [thick, magenta, domain=0:1/12,
MyArrowDecorationPlot={0.05}{1}{1.25}] {-4*x};
\addplot [thick, magenta, domain=0.4:1/12,
MyArrowDecorationPlot={0.05}{1}{1.25}] {-4*x};
\addplot [thick, violet, domain=-0.4:-1/8, MyArrowDecorationPlot] {+x};
\addplot [thick, violet, domain=0:-1/8, MyArrowDecorationPlot] {+x};
\addplot [thick, violet, domain=0:0.4, MyArrowDecorationPlot] {+x};
\addplot [very thick, fill=white, only marks] coordinates {(0,0) (-1/8,-1/8) (1/12,-1/3) (1/4,0)};
\end{axis}
\end{tikzpicture}
\end{document}
Figures
First figure with domain=-2:2
.
Second figure with domain=-0.4:0.4
. This new solution shows how to change the domain of the vector field and also how to show the decorated plots in the same direction as the vector field.
quiver
frompgfplots
is able to draw the arrows of a given vector field, drawing nullclines implies in finding them by solving an equation and then plotting the found equation.