7
$\begingroup$

Here is what I have thus far:

SetOptions[VectorPlot,
  VectorScale -> {0.045, .9, None},
  Axes -> True,
  AxesLabel -> {x, y},
  VectorPoints -> 16,
  VectorStyle -> {GrayLevel[0.8]}];
SetOptions[ContourPlot,
  ContourStyle -> {Orange, Green}];
SetOptions[ParametricPlot,
  PlotStyle -> Blue];

I made the above an initialization cell. Next, I have this:

Manipulate[
 Module[{f, g, tmin, tmax, xmin, xmax, ymin, ymax},
  tmin = -2; tmax = 2;
  xmin = -2; xmax = 4;
  ymin = -4; ymax = 2;
  f[x_, y_] = 2 x - y + 3 (x^2 - y^2) + 2 x y;
  g[x_, y_] = x - 3 y - 3 (x^2 - y^2) + 3 x y;
  ptRules = NSolve[{f[x, y] == 0, g[x, y] == 0}, {x, y}];
  z = NDSolveValue[{{x'[t], y'[t]} == {f[x[t], y[t]], 
         g[x[t], y[t]]}, {x[0], y[0]} == #}, {x[t], y[t]}, {t, tmin, 
       tmax}] & /@ u;
  Show[
   VectorPlot[{f[x, y], g[x, y]}, {x, xmin, xmax}, {y, ymin, ymax}],
   ContourPlot[{f[x, y] == 0, g[x, y] == 0}, {x, xmin, xmax}, {y, 
     ymin, ymax}],
   Graphics[{Red, PointSize[Large], Point[{x, y}] /. ptRules}],
   ParametricPlot[z, {t, tmin, tmax}]]],
 {{u, {}}, Locator, Appearance -> None, LocatorAutoCreate -> All},
 {z, {}, None}, Paneled -> False]

Running the manipulate gives this image.

enter image description here

Now use your mouse to click anywhere in the phase plane vector field and a solution trajectory will be drawn.

Now my question. Each time I click in the vector field, it shrinks, then expands, then draws. Can anything be done to stop this motion (shrink, expand on each click)?

Second question: The cell indicators on the right margin are blinking. What's up with that?

$\endgroup$
7
$\begingroup$

Updated:

added PlotTheme -> None so it does not blink when resizing the window. reference

Original

This works for me, no blinking and no change in size. Added PerformanceGoal -> "Speed" for the vector plot.

 Manipulate[Module[{f, g, tmin, tmax, xmin, xmax, ymin, ymax}, 
  tmin = -2; tmax = 2;
  xmin = -2; xmax = 4;
  ymin = -4; ymax = 2;
  f[x_, y_] = 2 x - y + 3 (x^2 - y^2) + 2 x y;
  g[x_, y_] = x - 3 y - 3 (x^2 - y^2) + 3 x y;
  ptRules = NSolve[{f[x, y] == 0, g[x, y] == 0}, {x, y}];
  z = NDSolveValue[{{x'[t], y'[t]} == {f[x[t], y[t]], g[x[t], y[t]]}, 
      {x[0], y[0]} == #}, {x[t], y[t]}, {t, tmin, tmax}] & /@ u;
  Show[VectorPlot[{f[x, y], g[x, y]}, {x, xmin, xmax}, {y, ymin, ymax}, 
   PerformanceGoal -> "Speed", PlotTheme -> None], 
   ContourPlot[{f[x, y] == 0, g[x, y] == 0}, {x, xmin, xmax}, {y, ymin, ymax}, 
   PerformanceGoal -> "Quality", PlotTheme -> None],
   Graphics[{Red, PointSize[Large], Point[{x, y}] /. ptRules}], 
   ParametricPlot[z, {t, tmin, tmax}, PlotTheme -> None]]
  ], 
  {{u, {}}, Locator, Appearance -> None, LocatorAutoCreate -> All}, 
   {z, {}, None}, Paneled -> False, 
 Initialization :> 
  {SetOptions[VectorPlot, VectorScale -> {0.045, .9, None}, Axes -> True, 
   AxesLabel -> {x, y}, VectorPoints -> 16, 
    VectorStyle -> {GrayLevel[0.8]}];
   SetOptions[ContourPlot, ContourStyle -> {Orange, Green}];
   SetOptions[ParametricPlot, PlotStyle -> Blue]}]

ps. I put the plot options in the manipulate. But it should work if you remove them outside.

$\endgroup$
  • $\begingroup$ Cool! Can something similar be done to keep the nullclines from crinkling and something to get the parametric plot to motion with more quality? $\endgroup$ – David Mar 24 '15 at 5:21
  • 1
    $\begingroup$ @David, isn't that the trade-off of quality for speed? $\endgroup$ – murray Mar 24 '15 at 15:22
  • $\begingroup$ @Nasser Excellent contributions! We are still experiencing blinking cell brackets when portions of both outputs are visible in one window. Any thoughts? Secondly, where do you think the Quiet command should be applied so that NDSolveValue doesn't report things? $\endgroup$ – David Mar 24 '15 at 16:00
  • $\begingroup$ @Michael E2 Could you also take a look at this project and help us answer the question about the blinking cell brackets? $\endgroup$ – David Mar 24 '15 at 16:11
  • $\begingroup$ @kguler Could you also take a look at our blinking cell bracket problem? $\endgroup$ – David Mar 24 '15 at 16:12
4
$\begingroup$

Here's my take with a view toward optimizing update/response time:

With[
 (* constants that won't change *)
 {vpopts = {VectorScale -> {0.045, .9, None}, Axes -> True,
    AxesLabel -> {x, y}, VectorPoints -> 16, 
    VectorStyle -> {GrayLevel[0.8]}},
  cpopts = {ContourStyle -> {Orange, Green}},
  ppopts = {PlotStyle -> Blue},
  tmin = -2, tmax = 2,
  xmin = -2, xmax = 4,
  ymin = -4, ymax = 2},
 Manipulate[
  (* parameters that might be changed by adding controls *)
  f = Function[{x, y}, 2 x - y + 3 (x^2 - y^2) + 2 x y];
  g = Function[{x, y}, x - 3 y - 3 (x^2 - y^2) + 3 x y];
  ptRules = NSolve[{f[x, y] == 0, g[x, y] == 0}, {x, y}]; 
  With[{background = Show[
    VectorPlot[{f[x, y], g[x, y]}, {x, xmin, xmax}, {y, ymin, ymax}, vpopts],
    ContourPlot[{f[x, y] == 0, g[x, y] == 0}, {x, xmin, xmax}, {y, ymin, ymax}, cpopts],
    Graphics[{Red, PointSize[Large], Point[{x, y}] /. ptRules}]
    ]},
   (* stuff that needs updating every click/drag *)
   Dynamic@Show[
     background,
     ParametricPlot[Evaluate[z /@ u], {t, tmin, tmax}, ppopts]
     ]
   ],
  {{u, {}}, Locator, Appearance -> None, LocatorAutoCreate -> All},
  {{z, z}, None}, {f, None}, {g, None}, {ptRules, None},
  Initialization :>
   (* stores (memoizes) solution after click *)
   (z[pt_] := If[$ControlActiveSetting, #, z[pt] = #] &@
     NDSolveValue[
      {{x'[t], y'[t]} == {f[x[t], y[t]], g[x[t], y[t]]}, {x[0], y[0]} == pt},
      {x[t], y[t]}, {t, tmin, tmax}]),
  Paneled -> False]
 ]

When I write a dynamic class example like this one, I think of symbols as falling into three categories: Some "variables" may really be constants; some may be parameters that are updated only to change the nature of the example; some are meant to be varied frequently to explore the example. Here I've somewhat arbitrarily divided according to what categories they could fall into, in order to illustrate the principle. If f and g are not to change, they can be moved into the With outside of Manipulate; and the With with the background could be nested between the outermost With and the Manipulate.

The Dynamic wrapping the Show means that only the Show is updated when the locators u change.

The solutions are cached in z when the mouse is released. It's unlikely that a user will re-click on a locator, since they're invisible. This means that the solutions will not be recalculated as new ones are added. Note that the declaration {{z, z}, None} means that z will be initialized to itself; in other words, it won't be set equal to 0, which occurs by default and which would break the SetDelayed definition in the Initialization option. Or in other-other words, it's an uninitialization initialization. :)

$\endgroup$
  • $\begingroup$ Amazing response. I am going to learn a lot, thanks to your help, and my students will benefit. $\endgroup$ – David Mar 24 '15 at 23:03
  • $\begingroup$ One comment you made in the code was (* parameters that might be changed by adding controls *). Can you share an example of you might change these functions by adding a control? $\endgroup$ – David Mar 25 '15 at 2:36
  • $\begingroup$ Never mind. Just discovered your response at http://mathematica.stackexchange.com/questions/78146/entering-an-differential-equation-in-a-manipulate-box. $\endgroup$ – David Mar 25 '15 at 2:38
  • $\begingroup$ @David, Another way is to have an InputField with the declaration {{vf, {2 x - y + 3 (x^2 - y^2) + 2 x y, x - 3 y - 3 (x^2 - y^2) + 3 x y}}, InputField}, and define {f, g} = Function @@ {{x, y}, #} & /@ vf in the body of the Manipulate. One could also have an input field {{$f, 2 x - y + 3 (x^2 - y^2) + 2 x y, "f"}, InputField} for each function and define f = Function @@ {{x, y}, $f}. $\endgroup$ – Michael E2 Mar 25 '15 at 2:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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