# TikZ Drawing a changing vector field in a grid

So far I succeeded in drawing a simple grid along with it's centres using grid and nodes.

\draw[step=1] (0, 0) grid (4, 3);

\coordinate (a) at (0.4, 0.3);
\coordinate (b) at (3.8, 0.8);

\draw[fill=white,thick,->] (a) -- (b);

\foreach \x in {0.5, 1.5, 2.5, 3.5} {
\foreach \y in {0.5, 1.5, 2.5} {
\node at (\x, \y)[circle, fill=black, scale=0.25] {};
}
}


However the nodes representing the centroids of the cells, I would also like to add a vector field. The vectors in a column should point in the same direction, but along the x axis they should point more in the upward direction as one goes to the right side (like Pi/8, Pi/4, 3*Pi/4, etc). It's clear to me how this would be programmed in a "normal" programming language, but I don't see how this fits into TikZ's foreach loop..

Also I'm wondering weather it's possible to have a curvilinear grid instead of a simple rectangular.

-
What I find really confusing that I couldn't figure out how to define scalar variables, just vectors?! –  Nils Jun 6 '11 at 12:33
Can you sketch what you mean by a "curvilinear grid" and post the image? –  Andrew Stacey Jun 6 '11 at 13:11

Put \usetikzlibrary{calc} on the preamble. Then use something like

\foreach \x in {0.5, 1.5, 2.5, 3.5} {
\foreach \y in {0.5, 1.5, 2.5} {
\node at (\x, \y)[circle, fill=black, scale=0.25] {};
\pgfmathsetmacro{\vx}{0.2}
\pgfmathsetmacro{\vy}{\x*0.2}
\draw[->] (\x,\y) -- (\x+\vx, \y+\vy);
}
}


Replace the expressions for \vx and \vy according to the mathematical expression you wish to use. If necessary you can also use trigonometric functions or other standard mathematical functions.

-
Soo.. \vx is a scalar? –  Nils Jun 6 '11 at 13:03
@Nils: yes, it is. You can set separately \vx and \vy, the two components of your vector field along x and y. –  Marco Lombardi Jun 6 '11 at 15:27

To iterate variables "simultaneously" TikZ has the following syntax: the list of variables must be separated by slashes /, and the list items can also be lists of values separated by slashes.

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\draw (0, 0) grid (4, 3);

\foreach \x/\angle in {0.5/20, 1.5/40, 2.5/60, 3.5/80} {
\foreach \y in {0.5, 1.5, 2.5} {
\draw[->,thick]  (\x, \y) -- ++(\angle:1);
}
}
\end{tikzpicture}

\end{document}


EDIT: here's a modified version using multiples of an angle expressed in radians:

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\def\angle{pi/8}
\pgfmathsetmacro{\dang}{deg(\angle)}
\draw (0, 0) grid (4, 3);

\foreach \x/\k in {0.5/1, 1.5/2, 2.5/3, 3.5/4} {
\foreach \y in {0.5, 1.5, 2.5} {
\draw[->,thick]  (\x, \y) -- ++(\k*\dang:1);
}
}
\end{tikzpicture}

\end{document}

-
Can you also specify the angle in rad using a constant symbol for PI? –  Nils Jun 6 '11 at 12:53
@Nils: pgf uses degrees (for hopefully obvious reasons) but the accompanying pgfmath package includes functions that translate between degrees and radians. So you would have to do the requisite conversion. \pgfmathsetmacro{\dang}{deg(\angle)} would do. –  Andrew Stacey Jun 6 '11 at 13:10
Gonzalo: One bit I changed was to use \fill (\x,\y) circle[radius=1pt]; for the circles. Just because one can draw nodes with circles doesn't mean that one should. –  Andrew Stacey Jun 6 '11 at 13:11
@Andrew: I edited my answer. Thank you. –  Gonzalo Medina Jun 6 '11 at 13:39
Thank you all for your answers/comment, I think the key is to use pgf math :) –  Nils Jun 6 '11 at 13:46

pgfplots can draw vector fields by means of its quiver plot handler.

\documentclass[a4paper]{article}

\usepackage{pgfplots}

\begin{document}
\thispagestyle{empty}
\begin{tikzpicture}
\begin{axis}[title=Quiver and plot table]
quiver={u=\thisrow{u},v=\thisrow{v}},
-stealth]
table
{
x y u v
0 0 1 0
1 1 1 1
2 4 1 4
3 9 1 6
4 16 1 8
};
\end{axis}
\end{tikzpicture}

\begin{tikzpicture}
\begin{axis}[
title={$x \exp(-x^2-y^2)$ and its gradient},
domain=-2:2,
view={0}{90},
axis background/.style={fill=white},
]
labels=false},thick]
{exp(0-x^2-y^2)*x};
quiver={
u={exp(0-x^2-y^2)*(1-2*x^2)},
v={exp(0-x^2-y^2)*(-2*x*y)},
scale arrows=0.3,
},
-stealth,samples=15]
{exp(0-x^2-y^2)*x};
\end{axis}
\end{tikzpicture}

\end{document}


It is restricted to rectangular grids, log coords or polar coords, though.

-