# Plot a function based on Derivative - Gradient field

I'm trying to plot the gradient field of a function in such a way that is possible to change it easily, only editing the function.

Consider the code:

xmin := -2; xmax := -xmin; ymin := -2; ymax := -ymin;
f[x_, y_] := x^2 + y^2
Plot3D[f[x, y], {x, xmin, xmax}, {y, ymin, ymax}]


So, the following code produces a very fancy result:

VectorPlot[{2 x, 2 y}, {x, xmin, xmax}, {y, ymin, ymax},
StreamPoints -> Coarse, StreamColorFunction -> Hue]


Since {D[f[x, y], x], D[f[x, y], y]} produces {2 x, 2 y} I tried to define

Gradf := {D[f[x, y], x], D[f[x, y], y]}


and use

VectorPlot[Gradf, {x, xmin, xmax}, {y, ymin, ymax},
StreamPoints -> Coarse, StreamColorFunction -> Hue]


but I got a lot of errors as

General::ivar: -1.99971 is not a valid variable. >>

General::stop: Further output of General::ivar will be suppressed during this calculation. >>

I really don't understand why it is not working.

Any idea how to solve this so I could only change the definition of f and plot again?

• Gradf[x_, y_] = {D[f[x, y], x], D[f[x, y], y]} instead of Gradf := .... Then it works perfectly. See here – Öskå May 22 '14 at 23:46
• It's basically trying to find the Derivative of your function with the x = some value, instead of the Variable x because of the SetDelayed. So it says "-1.9something is not a valid variable" with which it can find the derivative. It's like saying D[x,0]. – Öskå May 22 '14 at 23:48
• @Öskå, I'm getting Set::write: Tag List in {2 x,2 y}[x_,y_] is Protected. >>. The same with :=. – Sigur May 22 '14 at 23:49
• You can answer your own question if you like, enlightened by these comments :) If not, I will do it tomorrow. It's too late here for me to write a properly written answer :) – Öskå May 22 '14 at 23:56
• Why not just the following? With[{gradient = Grad[f[x, y], {x, y}]}, VectorPlot[gradient, {x, xmin, xmax}, {y, ymin, ymax}, StreamPoints -> Coarse, StreamColorFunction -> Hue]] – murray May 24 '14 at 15:01

The problem is that by defining Gradf as fun := D[x^2,x] you are saying "Ok, you will find the Derivative of x^2 in terms of x later on." by using SetDelayed (:=).

Thus, when fun appears in your VerctorPlot or more generally Plot, Mathematica sees it as: "Ok, now I'm going to find the Derivative of fun in terms of x, for each x = {0, 10}":

Plot[fun, {x, 0, 10}]


General::ivar: 0.0002042857142857143 is not a valid variable.

meaning that Mathematica, as you commanded, is trying to find the Derivative of x^2 in terms of x with x equal to 0.0002042857142857143 (case n°1 bellow). Which is obviously not possible since x is not a Variable anymore.

A part of the excellent answer from rm-rf here says:

• If you're plotting a function, whose definition depends on the output of another possibly expensive computation (such as Integrate, DSolve, Sum, etc. and their numerical equivalents) use = or use an Evaluate with :=. Failure to do so will redo the computation for every plot point! This is the #1 reason for "slow plotting".

Then all you have to do is to follow what has been said above: defining your function with Set (=) so it Evaluates the function to x before plotting it (case n°2 bellow), or Evaluate fun inside Plot so it Evaluates the fun to x before plotting (case n°3 bellow). What is internally happening can be seen with Trace:

Trace@With[{fun := D[x^2, x]}, Plot[fun, {x, 0, 10}]]


Trace@With[{fun = D[x^2, x]}, Plot[fun, {x, 0, 10}]]


Trace@With[{fun := D[x^2, x]}, Plot[Evaluate@fun, {x, 0, 10}]]


Now to answer the question on your specific case you have two possibilities:

xmin := -2; xmax := -xmin; ymin := -2; ymax := -ymin;
f[x_, y_] := x^2 + y^2

With[{Gradf = {D[f[x, y], x], D[f[x, y], y]}},
VectorPlot[Gradf, {x, xmin, xmax}, {y, ymin, ymax},
StreamPoints -> Coarse, StreamColorFunction -> Hue]]

(* or *)

With[{Gradf := {D[f[x, y], x], D[f[x, y], y]}},
VectorPlot[Evaluate@Gradf, {x, xmin, xmax}, {y, ymin, ymax},
StreamPoints -> Coarse, StreamColorFunction -> Hue]]


• Thanks so much. I didn't know about Trace. Very interesting. – Sigur May 23 '14 at 16:45
• @Sigur You are welcome :) I hope it helped you to understand what's really happening inside the box :) – Öskå May 23 '14 at 16:57
• Do you know how to plot the integral curve of the Grad field and also its image on the surface to show the path of highest grow level? – Sigur May 27 '14 at 0:59
• @Sigur I'm afraid that I don't really understand what you intend to do.. :) Assuming that the "surface" is the Plot3D`, what would you exactly like to do? – Öskå May 27 '14 at 11:00
• Ow, sorry. I'd like to plot on the 3d surface the path obtained applying the function to the path on domain corresponding to the Grad directions, that is, perpendicular to level curves. So I could see the path on the surface where the function has the faster growth. For some functions, this is easy (for example, $z=x^2+y^2$). – Sigur May 27 '14 at 23:13