1
$\begingroup$

I have this piece of code which plots certain streamlines in a Manipulate environment:

ph[r_, th_, a_] := r^(Pi/a) Cos[Pi/a th];
g[r_, th_] := {r Cos[th], r Sin[th]} 
pp[a_] := 
 Module[{pl}, 
  pl = StreamPlot[{D[ph[r, th, a], th]/r, -D[ph[r, th, a], r]/r}, {r, 
     0.1, 3}, {th, 0, a}, 
    StreamPoints -> 
     Join[Table[{rs, 0}, {rs, 0.1, 3.0, 0.2}], 
      Table[{rs, a}, {rs, 0.1, 3.0, 0.2}]], 
    StreamStyle -> {"Line", Darker[Blue]}] ;
  pl[[1, 2, 1]] = g @@@ pl[[1, 2, 1]];
  pl]
Manipulate[
 Show[pp[\[Alpha]], PlotRange -> {{-3, 3}, {-3, 3}}], {\[Alpha], Pi/8,
   15 Pi/8}, SaveDefinitions -> True]

The module creates a plot of the streamlines in an r-th plane first, and then transforms the plot into Cartesian coordinates. The code works fine, in principle, but whenever I grab the slider the graphics turns red, and I can see that Manipulate shows the StreamPlot in the r-th plane until I let go of the slider, at which point Manipulate shows the correct plot.

Why is this happening, and how can I fix it?

$\endgroup$
  • $\begingroup$ Probably because you use g@@@. $\endgroup$ – Feyre Oct 30 '16 at 14:10
  • $\begingroup$ But what's wrong with doing that? What can/should I use instead? $\endgroup$ – Pirx Oct 30 '16 at 14:13
  • $\begingroup$ Nothing specifically wrong with it, but I think it's somehow not running properly when you drag the slider. The error it gives is "g is not a graphics primitive". $\endgroup$ – Feyre Oct 30 '16 at 14:14
  • $\begingroup$ When the control moves, the system changes $PerformanceGoal = "Speed", which causes StreamPlot not to produce a GraphicComplex based output. Your use of pl[[1,2,1]] assumes the output is of this form. Try setting the option PerformanceGoal -> "Quality" explicitly in StreamPlot and see if it responds adequately quickly. $\endgroup$ – Michael E2 Oct 30 '16 at 14:32
  • $\begingroup$ Ahah! Yes, setting PerformanceGoal->Quality still gives adequate response. Thanks! $\endgroup$ – Pirx Oct 30 '16 at 14:38
2
$\begingroup$

When the control moves, the system changes $PerformanceGoal to "Speed", which causes StreamPlot not to produce a GraphicComplex based output. The use of pl[[1,2,1]] assumes the output is of this form. One can try setting the option PerformanceGoal -> "Quality" explicitly in StreamPlot and see if the response time is satisfactory.

pp[a_] := 
 Module[{pl}, 
  pl = StreamPlot[{D[ph[r, th, a], th]/r, -D[ph[r, th, a], r]/r},
    {r, 0.1, 3}, {th, 0, a}, 
    StreamPoints -> 
     Join[Table[{rs, 0}, {rs, 0.1, 3.0, 0.2}], 
      Table[{rs, a}, {rs, 0.1, 3.0, 0.2}]], 
    StreamStyle -> {"Line", Darker[Blue]}, 
    PerformanceGoal -> "Quality"];
  pl[[1, 2, 1]] = g @@@ pl[[1, 2, 1]];
  pl]

If performance is an issue, then using ReplaceAll may be more robust. (To further improve performance, one could use ControlActive to speed up dynamic interactivity.)

pp[a_] := 
 Module[{pl}, 
  pl = StreamPlot[{D[ph[r, th, a], th]/r, -D[ph[r, th, a], r]/r},
    {r, 0.1, 3}, {th, 0, a},
    StreamPoints -> 
     Join[Table[{rs, 0}, {rs, 0.1, 3.0, ControlActive[0.4, 0.2]}], 
      Table[{rs, a}, {rs, 0.1, 3.0, ControlActive[0.4, 0.2]}]],
    StreamStyle -> {"Line", Darker[Blue]}];
  pl /. (h : GraphicsComplex | Arrow)[p_, rest___] :> h[g @@@ p, rest]]

If you wish to avoid arrows during active manipulation of the control, change the replacement rule to

(h : GraphicsComplex | Arrow | Line)[p_?MatrixQ, rest___] :>
  {Arrowheads[0], h[g @@@ p, rest]}
$\endgroup$

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.