# 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, 2014 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, 2014 at 23:48
• @Öskå, I'm getting Set::write: Tag List in {2 x,2 y}[x_,y_] is Protected. >>. The same with :=. May 22, 2014 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, 2014 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]] May 24, 2014 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. May 23, 2014 at 16:45
• @Sigur You are welcome :) I hope it helped you to understand what's really happening inside the box :)
– Öskå
May 23, 2014 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? May 27, 2014 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, 2014 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$). May 27, 2014 at 23:13