# Making the size of the arrow head proportional to the magnitude of a vector field in TikZ

Consider a scaled vector field v = (-x, 2x+y-1) living on the triangle at (0,1), (1,0), and (0,0):

\documentclass{minimal}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}

\coordinate (A) at (0,0);
\coordinate (B) at (1,0);
\coordinate (C) at (0,1);

\draw[thick] ($(A)$) -- ($(B)$) -- ($(C)$)-- cycle;
\foreach \x in {1, 2, ..., 10}
\foreach \y in {0, 1, ..., \x}
{\draw [-stealth,blue] ($(B)-(0.1,0)+0.1*(1-\x,\y)$)
-- ++(0.02*\x - 0.2, -0.04*\x + 0.4 +0.02*\y-0.2);}
\end{tikzpicture}
\end{document}


The output is as follows:

Comparing with the vector fields drawn by MATLAB's quiver:

The MATLAB's quiver command automatically scales the size of the arrow heads according to the magnitude of the vector.

So my question is: how do we scale the size of the arrow heads in TikZ? Preferably in MATLAB's solution, the vector field vanishes at (0,1) so there is no arrow there.

For example I googled a little bit, and wonder if pgfmath could do some calculation about the length variable \l. Then doing something like will work:

\draw [-stealth,blue, single arrow head extend=\l mm] ($(B)-(0.1,0)+0.1*(1-\x,\y)$)
-- ++(0.02*\x - 0.2, -0.04*\x + 0.4 +0.02*\y-0.2);


Thanks.

• The arrow tip’s size is usually defined in dependence of the line width. One answer of Is it possible to change the size of an arrowhead in TikZ/PGF? should help here. Commented Sep 19, 2013 at 20:54
• @Qrrbrbirlbel Thank you sir. That's very informative. How to put some calculated length into the option of the \draw command? For example \draw [-stealth,blue, single arrow head extend=\x mm] Commented Sep 19, 2013 at 21:12
• @Qrrbrbirlbel Thank you so much sir, I have used that new arrow library to make up an answer to my own question. Commented Sep 20, 2013 at 16:20

You could use PGFPlots' quiver functionality together with a bit of coordinate filtering to achieve this:

\documentclass{article}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
view={0}{90},
axis equal image,
hide axis, clip=false
]
blue,
point meta={sqrt(x^2+(2*x+y-1)^2)},
quiver={
u={-x}, v={2*x+y-1},
scale arrows=0.1,
every arrow/.append style={
line width=2pt*\pgfplotspointmetatransformed/1000,
-latex
},
},
samples=10,
domain=0:1, y domain=0:1,
y filter/.append code={\pgfmathparse{(x+y)>1 ? nan : y}},
x filter/.append code={\pgfmathparse{(sqrt(x^2+(2*x+y-1)^2))==0 ? nan : x}}
] (x,y,0);

\draw (axis cs:0,0) -- (axis cs:1,0) -- (axis cs:0,1) -- cycle;
\end{axis}
\end{tikzpicture}

\end{document}

• Thanks, this is nice. :) If there is no other pure TikZ solutions, I will accept your answer. Commented Sep 19, 2013 at 21:13
• @ShuhaoCao: what do you mean with pure TikZ? Pgfplots is built as an extension of TikZ so... Commented Sep 20, 2013 at 6:23
• How to use quiver? I'm getting the error pgfkeys: I do not know the key '/tikz/quiver' and I am going to ignore it. Perhaps you misspelled it. ] (x,y,0); Commented Oct 16, 2013 at 0:31
• @Sigur: You may be using an old version of PGFPlots, I think you need at least version 1.4 for the quiver plots.
– Jake
Commented Oct 16, 2013 at 5:46
• @Jake, thanks. I've installed the newer one and it's working fine. Commented Oct 16, 2013 at 11:55

Based on Qrrbrbirlbel's comment I have come up with my own solution as well besides the nice answer using quiver by Jake. I am using the New arrows library in this question made by Luigi (and it is great!): Is it possible to change the size of an arrowhead in TikZ/PGF?

You can download the two .tex files in the sourceforge link Luigi gave, and put them in the same directory of your main file then you can compile it using pdflatex or xelatex.

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{arrows,arrows.new}
\begin{tikzpicture}[scale=4]
\coordinate (A) at (0,0);
\coordinate (B) at (1,0);
\coordinate (C) at (0,1);
\draw[thick] ($(A)$) -- ($(B)$) -- ($(C)$)-- cycle;

\foreach \x in {1, 2, ..., 10}
\foreach \y in {0, 1, ..., \x}
($(B)-(0.1,0)+0.1*(1-\x,\y)$)

A major difference between above solution with the solution using PGFplots's quiver is that, by default, quiver scales the thickness of the arrow's body as well, here using this approach the arrow thickness is unchanged, only the size of the arrow heads are changed.