Direction Fields


Direction fields could be visualized by plotting either a list of vectors or a selection of streamlines. Correspondingly, Mathematica uses two special commands to plot diection fields: VectorPlot and StreamPlot. Both commands require vector-valued input: one for abscissa (usually labeled by x or t) and another for ordinate. Therefore, to plot a direction field for a first order differential equation \( {\text d}y / {\text d}x = f(x,y) , \) a user needs to set 1 for the first coordiante and f for the second one, so making the vector input \( \left( 1, f(x,y) \right) . \) Bisides, Mathematica also offers their variations: ListContourPlot, VectorDensityPlot, ListVectorPlot, ListVectorDensityPlot, ListStreamPlot, ListDensityPlot, StreamDensityPlot, ListStreamDensityPlot, and LineIntegralConvolutionPlot. Their applications will be clear from presented examples here and within first two parts.

Since by default, VectorPlot automatically enlarges/stretches the lengths of vectors, Mathematica offers an option, VectorScale to suppress changes in vector lengths. Let us look at two outputs generated without and with this option:

 

VectorPlot[{y, -x}, {x, -3, 3}, {y, -3, 3}] /. ar : Arrow[{p1_, p2_}] :> Tooltip[Arrow[{p1, p2}], p1]
VectorPlot[{-y, x}, {x, -4, 4}, {y, -4, 4}, VectorScale -> {0.045, 0.9, None}, VectorPoints -> 16]

Sometimes we need to include axes into the direction field; this can be achieved, for instance, by enlarging the plotted area, as the following examples show.

sys = {u (1 - u + a v), r v (1 - v + b u)};
vp = VectorPlot[
sys /. {a -> 1/4, b -> 2, r -> 1}, {u, 0, 2}, {v, 0, 2},
VectorScale -> {0.045, 0.9, None}, VectorStyle -> {GrayLevel[0.2]},
Axes -> True, AxesLabel -> {x, y}, AxesOrigin -> {0, 0}]
sys = {u (1 - u + a v), r v (1 - v + b u)};
vp = VectorPlot[
sys /. {a -> 1/4, b -> 2, r -> 1}, {u, -0.2, 2}, {v, -0.2, 2},
VectorScale -> {0.045, 0.9, None}, VectorStyle -> {GrayLevel[0.2]},
Axes -> True, AxesLabel -> {x, y}, AxesOrigin -> {0, 0}]
   
Vector plot without axes (left) and with axes (right).

Ideally we'd get something like a tooltip which shows the x,y position where I click (or where the mouse is currently hovering) and the evaluated vector (or scalar in the case of a scalar field) at that position. I think this would be a great way to "get a feel for" the values because by default the arrows are scaled automatically so they fit so I don't know anything about the relative magnitude of a particular arrow.

VectorPlot[{y, -x}, {x, -3, 3}, {y, -3, 3}] /. ar : Arrow[{p1_, p2_}] :> Tooltip[Arrow[{p1, p2}], p1]
LocatorPane[{x,y}, back] back Mathematica LocatorPane[Dynamic[pt], back]
f[x_, y_] := {-1 - x^2 + y, 1 + x - y^2}
DynamicModule[{pt = {1, 0}},LocatorPane[Dynamic[pt],
VectorPlot[f[x, y], {x, -3, 3}, {y, -3, 3}, StreamPoints -> Coarse,
StreamColorFunction -> Hue, Epilog -> Dynamic@Inset[{pt, f @@ pt}, pt],
PerformanceGoal -> "Quality"], AutoAction -> True, Appearance -> Style["\[FilledCircle]", Red]]]
Export["pointdir.png", %]
Direction field for the vector equation.

VectorPlot[{1, (y + Exp[x/2])/(x + Exp[y])}, {x, 0, 3}, {y, -1, 2}]


 One can draw the direction field either with arrows

VectorPlot[{1, y^3 - 8*x}, {x, -1, 5}, {y, -5, 5}, VectorPoints -> 16, VectorStyle -> Arrowheads[0.028], Axes -> True]

or with drop feature

VectorPlot[{1, y^3 - 8*x}, {x, -1, 5}, {y, -5, 5}, VectorPoints -> 10, VectorStyle -> "Drop", Axes -> True]

For plotting streamlines and their solutions, Mathematica has a dedicated command: StreamPlot. Streamlines are similar to vector lines except this command creates lines connecting the different values instead of arrows at each point.

f[x_, y_] = (y + E^(x/2))/(x + E^(2*y))
StreamPlot[{1, f[x, y]}, {x, 0, 10}, {y, -20, 5}, Frame -> False, Axes -> True, AspectRatio -> 1/GoldenRatio]


StreamPlot[{1, f[x, y]}, {x, 0, 10}, {y, -20, 5}, Frame -> True, Axes -> True, AspectRatio -> 1/GoldenRatio,
StreamPoints -> {{{{1, 2}, Green}, {{9.5, -1}, Red}}}]
StreamPlot[{1, f[x, y]}, {x, 0, 10}, {y, -20, 5}, Frame -> True, Axes -> True, AspectRatio -> 1/GoldenRatio,
StreamPoints -> {{{{1, 2}, Green}, {{9.5, -1}, Red}, Automatic}}]
VectorDensityPlot[{1, f[x, y]}, {x, 1, 4}, {y, -15, 1}, AspectRatio -> 1/GoldenRatio]
StreamDensityPlot[{1, (y + Exp[x/2])/(x + Exp[y])}, {x, 0, 3}, {y, -1, 2},
ColorFunction -> "ThermometerColors"]