I am plotting the voltage in a pool of water with two electrodes.

I have contour lines on my graph at every volt, but I would like to show the electric field lines which are going to be perpendicular to the contour lines. How can I do that?

enter image description here

  • 1
    $\begingroup$ Have a look at this. It's 2D, so not a duplicate, but related. $\endgroup$
    – Jens
    Jan 30, 2013 at 16:21

2 Answers 2


What you're asking for could be done, but perpendicular contour lines are not a good way to represent the electric field in a 3D plot of a 2D potential. The electric field (or negative gradient) will be a vector field in the plane, and its field lines will be planar too. The third dimension in your 3d plot is geometrically meaningless because it doesn't have dimension length.

So instead what I'd strongly suggest is to either plot your potential and field in 2D, or plot the electric field as planar vectors attached to the 3D plot of the potential. The latter is what I'm illustrating below, because it's most closely matched to your starting point:

fieldArrow[pos_, field_, scale_] := {Hue[Norm[field]], 
   Arrowheads[.02], Arrow[Tube[{{pos, pos + scale field}}]]};

grid = Table[{x, y}, {y, 0, 10, .5}, {x, 0, 10, .5}];

gridData = 
  Table[Sin[y/10] ArcTan[x - 5], {y, 0, 10, .5}, {x, 0, 10, .5}];

fieldX = -DerivativeFilter[gridData, {0, 1}, 
    InterpolationOrder -> 3];
fieldY = -DerivativeFilter[gridData, {1, 0}, 
    InterpolationOrder -> 3];
data3D = MapThread[Append[#1, #2] &, {grid, gridData}, 2];

vectorField = 
   fieldArrow[Append[#1, #2], {#3, #4, 0}, 3] &, {grid, gridData, 
    fieldX, fieldY}, 2];

arrows = Graphics3D[vectorField];

Show[ListPlot3D[Flatten[data3D, 1], MeshFunctions -> (#3 &)], arrows]

field and potential

Here, I take the gradient of a made-up potential given as data, by using GradientFilter. Then I make arrows out of the field vectors and superimpose them on your original plot with Show.

It's up to you to style the arrows differently - I colored them by the field strength and scaled them by a parameter scale in the function fieldArrow. You may also want to shrink the arrowheads proportionally to the arrow length. But I left that out so you can see the smaller arrows better.


One can do what you ask, but you might prefer to follow the advice of @Jens. Here's how, anyway. First, I made up some data for a similar potential function.

data = Table[10 + (3 ((20 - j)^2 - (j + 5)^2))/(75 + (i - 10)^2 + 2 (j - 10)^2),
     {j, 0, 20}, {i, 0, 20}];
f = ListInterpolation[data, {{0, 20}, {0, 20}}];

Then we combine a plot of the potential and a stream plot of the negative gradient field, mapping the streamlines onto the graph of the potential (edited).

pot = Plot3D[f[x, y], {x, 0, 20}, {y, 0, 20}, MeshFunctions -> {#3 &},
   Mesh -> 14, FaceGrids -> All];
vf = StreamPlot[Evaluate[-D[f[x, y], {{x, y}}]], {x, 0, 20}, {y, 0, 20}, 
  StreamStyle -> "Line"];
 Graphics3D[vf[[1]] /. {{x_Real, y_Real} :> {x, y, f[x, y]}}]

Potential with contours and gradient lines

An alternative presentation might be the graph of the potential alongside a combined plot of the contours/gradient paths.

vf = StreamPlot[Evaluate[-D[f[x, y], {{x, y}}]], {x, 0, 20}, {y, 0, 20}, 
  StreamStyle -> ColorData[1][3]];
cp = Show[ContourPlot[f[x, y], {x, 0, 20}, {y, 0, 20}, Contours -> 14], vf];
Row[{Show[pot, ImageSize -> 300], Show[cp, ImageSize -> 250]}]

Potential and contour plots

  • $\begingroup$ It does look nice, though (+1). $\endgroup$
    – Jens
    Jan 31, 2013 at 4:48
  • $\begingroup$ +1 btw maybe an option of StreamStyle -> "Line" would make it more accordant with what OP asked for lines. $\endgroup$
    – Silvia
    Feb 1, 2013 at 15:49
  • $\begingroup$ @Silvia Thanks. I'd forgotten about such options and had to replace Arrow by Line. It's simpler now (in the edit), although I kept the arrows for the plane contour plot. Maybe someday Mathematica will have an option Mesh -> "Gradient" :) $\endgroup$
    – Michael E2
    Feb 2, 2013 at 16:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.