# pgfplots: how to connect points in a ternary plot with stealth/quiver

Suppose I have the classical example of a ternary plot in the PGFPlots.net website https://pgfplots.net/ternary-diagram-density-map/. The LaTeX code can be found below with small modifications to the original example. I need to introduce one single novelty to that plot: connecting the sequence of points. That is, I need to connect the sequence of points according to the order that they appear in the table (starting at the first point and finishing at the last one) with stealth or a quiver (I do not know which one works better in this situation), such that the points can be seen as representing the evolution of a dynamic process. I have tried quite hard but failed, and there is no example in the pgfplots documentation, neither in TEX forums. Help would be very much appreciated.

A similar type of ternary plots incorporating dynamics can be found (using Mathematica and continuous-time) here https://locusofctrl.github.io/blog/posts-output/2019-02-03-male-strategy/

\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{width=7cm,compat=1.8}
\usepgfplotslibrary{ternary}
\renewcommand*{\familydefault}{\sfdefault}
\usepackage{amsmath}
\begin{document}

\begin{tikzpicture}
\begin{ternaryaxis}[colorbar, colormap/jet,
%title={$x \exp(-x^2-y^2)$ and its gradient},
xmin = 0,
xmax = 100,
ymin = 0,
ymax = 100,
zmin = 0,
zmax = 100,
xlabel = {$x_1$},
ylabel = {$x_2$},
zlabel = {$x_3$},,
grid   = both,
%label style    = {sloped},
minor tick num = 1,
]
point meta=\thisrow{myvalue}, %  uses ’point meta’ as color data.
nodes near coords*={\tiny{\pgfmathprintnumber\myvalue}}, %does what it says
visualization depends on={\thisrow{myvalue} \as \myvalue} %defines visualization dependency
] table {
x       y       z       myvalue
10      0       90      7.1
40      0       60      9.2
50      0       50      9.8
70      0       30      8.5
20      30      50      5.5
20      20      40      5
20      50      30      4.8
30      40      30      6.3
30      20      50      7.1
40      20      40      7.8
40      30      30      7.4
40      40      20      6.9
40      50      10      6.7
10      10      80      4.7
10      20      70      4.2
10      30      60      3.7
10      40      50      3.5
10      50      40      3.2
10      70      20      4.8
10      80      10      5.2
50      30      20      7.8
50      20      30      8.3
60      10      30      9
70      20      10      9.2
80      10      10      9.9
20      10      70      6.2
40      60      0       6.6
70      30      0       9.3
50      10      40      8.9
20      20      60      5.9
};
\end{ternaryaxis}
\end{tikzpicture}
\end{document}

• I know that if I replace the code only marks by -stealth, all the pairs of points will be connected by a straight line. This is part of the solution. What I need is to have also an arrow at the end of each connection. Commented Mar 25, 2021 at 22:24

After trying different approaches, I came out with a solution that may not be the most elegant one, but it works.

\documentclass[border=15mm]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{pgfplots}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\pgfplotsset{compat=1.17}
\usepgfplotslibrary{ternary}

\begin{document}
\begin{tikzpicture}
\begin{ternaryaxis}[
ylabel = {$x_2$},
zlabel = {$x_3$},
xlabel = {$x_1$},
ternary limits relative=false,
grid   = both,
%minor tick num = 1,
]
%-stealth, blue, semithick
%only marks
]
coordinates {
(0.80, 0.20, 0.00)
(0.76, 0.17, 0.07)
(0.66, 0.16, 0.16)
(0.20, 0.50, 0.30)
(0.40, 0.60, 0.00)
(0.60, 0.30, 0.10)
(0.40, 0.10, 0.50)
(0.10, 0.30, 0.60)
(0.00, 0.00, 1.00)
};

\draw [-stealth, thin, blue ,shorten >=0.09cm] (axis cs: 0.80, 0.20, 0.00)--(axis cs: 0.76, 0.17, 0.07);
\draw [-stealth, thin, blue ,shorten >=0.09cm] (axis cs: 0.76, 0.17, 0.07)--(axis cs: 0.66, 0.16, 0.16);
\draw [-stealth, thin, blue ,shorten >=0.09cm] (axis cs: 0.66, 0.16, 0.16)--(axis cs: 0.20, 0.50, 0.30);
\draw [-stealth, thin, blue ,shorten >=0.09cm] (axis cs: 0.20, 0.50, 0.30)--(axis cs: 0.40, 0.60, 0.00);
\draw [-stealth, thin, blue ,shorten >=0.09cm] (axis cs: 0.40, 0.60, 0.00)--(axis cs: 0.60, 0.30, 0.10);
\draw [-stealth, thin, blue ,shorten >=0.09cm] (axis cs: 0.60, 0.30, 0.10)--(axis cs: 0.40, 0.10, 0.50);
\draw [-stealth, thin, blue ,shorten >=0.09cm] (axis cs: 0.40, 0.10, 0.50)--(axis cs: 0.10, 0.30, 0.60);
\draw [-stealth, thin, blue ,shorten >=0.09cm] (axis cs: 0.10, 0.30, 0.60)--(axis cs: 0.00, 0.00, 1.00);

\end{ternaryaxis}
\end{tikzpicture}
\end{document}



This should produce the following output:

• +1: From my understanding, you do not need axis cs: since it is the default. Commented Mar 27, 2021 at 1:48
• No, there is a small detail that makes all the difference. If we do not split the path (using ´axis cs:´, we get the connector lines but not the arrows. But to have the connectors (without the arrows), we do not need at all the last block of the code: the \draw entries. That is, it will be just necessary to add [-stealth] after \addplot3+. But I needed the arrows as well. So, the splitting of the paths is required. Commented Mar 27, 2021 at 13:16

I think, you could parse the plot table multiple times. For this, you can read it in via \pgfplotstableread.

I further added clipped=false to the axis options, because otherwise the arrow heads would be clipped at the plot borders.

\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{width=7cm,compat=1.8}
\usepgfplotslibrary{ternary}
\renewcommand*{\familydefault}{\sfdefault}
\usepackage{amsmath}
x       y       z       myvalue
10      0       90      7.1
40      0       60      9.2
50      0       50      9.8
70      0       30      8.5
20      30      50      5.5
20      20      40      5
20      50      30      4.8
30      40      30      6.3
30      20      50      7.1
40      20      40      7.8
40      30      30      7.4
40      40      20      6.9
40      50      10      6.7
10      10      80      4.7
10      20      70      4.2
10      30      60      3.7
10      40      50      3.5
10      50      40      3.2
10      70      20      4.8
10      80      10      5.2
50      30      20      7.8
50      20      30      8.3
60      10      30      9
70      20      10      9.2
80      10      10      9.9
20      10      70      6.2
40      60      0       6.6
70      30      0       9.3
50      10      40      8.9
20      20      60      5.9
}{\mytable}

\begin{document}
\begin{tikzpicture}
\begin{ternaryaxis}[colorbar, colormap/jet,
%title={$x \exp(-x^2-y^2)$ and its gradient},
xmin = 0,
xmax = 100,
ymin = 0,
ymax = 100,
zmin = 0,
zmax = 100,
xlabel = {$x_1$},
ylabel = {$x_2$},
zlabel = {$x_3$},,
grid   = both,
%label style    = {sloped},
minor tick num = 1,
clip=false
]
point meta=\thisrow{myvalue}, %  uses ’point meta’ as color data.
nodes near coords*={\tiny{\pgfmathprintnumber\myvalue}}, %does what it says
visualization depends on={\thisrow{myvalue} \as \myvalue} %defines visualization dependency
] table {\mytable};
\foreach \row in {1,...,29} {
\pgfmathparse{\row-1}
\pgfplotstablegetelem{\pgfmathresult}{x}\of{\mytable}
\let\lastx=\pgfplotsretval
\pgfplotstablegetelem{\pgfmathresult}{y}\of{\mytable}
\let\lasty=\pgfplotsretval
\pgfplotstablegetelem{\pgfmathresult}{z}\of{\mytable}
\let\lastz=\pgfplotsretval
\pgfplotstablegetelem{\row}{x}\of{\mytable}
\let\thisx=\pgfplotsretval
\pgfplotstablegetelem{\row}{y}\of{\mytable}
\let\thisy=\pgfplotsretval
\pgfplotstablegetelem{\row}{z}\of{\mytable}
\let\thisz=\pgfplotsretval
\addplot3+[mark={}, -stealth, shorten >=3pt, solid, black] coordinates { (\lastx, \lasty, \lastz) (\thisx, \thisy, \thisz) };
}
\end{ternaryaxis}
\end{tikzpicture}
\end{document}


• Well, this is great. No problem if the table entries are quite large. My clumsy approach was not that good for such a case. Commented Mar 27, 2021 at 1:38
• It was still good, because it brought up the idea of splitting up the path, which is essentially needed in order to get multiple arrows. Commented Mar 27, 2021 at 1:40
• +1: The clipped=false is a clever move! Commented Mar 27, 2021 at 1:50