3
$\begingroup$

I often use a version of @Rahul's myStreamPlot (original here) to make nice looking StreamPlots. Briefly, it rescales the axes to achieve a more even distribution of streams.

Options[myStreamPlot] = Options[StreamPlot];
myStreamPlot[f_, {x_, x0_, x1_}, {y_, y0_, y1_}, opts : OptionsPattern[]] := 
Module[{u, v, a = OptionValue[AspectRatio]},
  Show[StreamPlot[{1/(x1 - x0), a/(y1 - y0)} (f /. {x -> x0 + u (x1 - x0), y -> y0 + v/a (y1 - y0)}), {u, 0, 1}, {v, 0, a}, opts]
  /. Arrow[pts_] :> Arrow[({x0, y0} + {x1 - x0, (y1 - y0)/a} #) & /@ pts], PlotRange -> {{x0, x1}, {y0, y1}}]]

Unfortunately any RegionFunction option doesn't get rescaled. For example,

StreamPlot[{Sin[2 π x], Sin[2 π y]}, {x, -1, 1}, {y, -1, 1},
  RegionFunction -> Function[{x, y, vx, vy, n}, x^2 + y^2 < 1]]

Mathematica graphics

looks good while

myStreamPlot[{Sin[2 π x], Sin[2 π y]}, {x, -1, 1}, {y, -1, 1},
  RegionFunction -> Function[{x, y, vx, vy, n}, x^2 + y^2 < 1]]

Mathematica graphics

doesn't.

Could someone suggest a way to rescale the RegionFunction inside myStreamPlot to deal with this issue? I tried myself but couldn't figure out how to modify it.

$\endgroup$
1
  • 3
    $\begingroup$ does RegionFunction -> Function[{x, y, vx, vy, n}, Rescale[x, {0, 1}, {-1, 1}]^2 + Rescale[y, {0, 1}, {-1, 1}]^2 < 1] give the desired result? $\endgroup$ – kglr Mar 14 '19 at 22:19
2
$\begingroup$

This works for RegionFunctions that depend only on the first two arguments:

ClearAll[myStreamPlot2]
Options[myStreamPlot2] = Options[StreamPlot];
myStreamPlot2[f_, {x_, x0_, x1_}, {y_, y0_, y1_}, opts : OptionsPattern[]] := 
 Module[{u, v, a = OptionValue[AspectRatio] /. Automatic -> 1, 
    rf = OptionValue[RegionFunction]}, 
  Show[StreamPlot[{1/(x1 - x0), a/(y1 - y0)} 
    (f /. {x->Rescale[u, {0, 1}, {x0, x1}], y->Rescale[v, {0, a}, {y0, y1}]}),
  {u, 0, 1}, {v, 0, a}, 
  RegionFunction -> (rf[Rescale[#, {0, 1}, {x0, x1}], Rescale[#2, {0, a}, {y0, y1}], ##3]&),
  opts] /. Arrow[pts_] :> Arrow[Transpose[{Rescale[#, {0, 1}, {x0, x1}], 
     Rescale[#2, {0, a}, {y0, y1}]} & @@ Transpose[pts]]], 
  PlotRange -> {{x0, x1}, {y0, y1}}]]

Row[myStreamPlot2[{Sin[2 π x], Sin[2 π y]}, {x, -1, 1}, {y, -1, 1}, AspectRatio -> #, 
    RegionFunction -> (#^2 + #2^2 < 1 &), ImageSize -> #2] & @@@ 
  Transpose[{{1/2, 1, 3/2}, {400, 300, 260}}], Spacer[5]]

enter image description here

$\endgroup$
2
  • $\begingroup$ This is perfect, thanks! $\endgroup$ – Chris K Mar 15 '19 at 20:21
  • $\begingroup$ @Chris, my pleasure. Thank you for the accept. $\endgroup$ – kglr Mar 15 '19 at 20:22
3
$\begingroup$

@kglr, yes that works. Here is a modified myStreamPlot:

myStreamPlot[f_, {x_, x0_, x1_}, {y_, y0_, y1_}, opts : OptionsPattern[]] := 
 Module[{u, v, a = OptionValue[AspectRatio], rf = OptionValue[RegionFunction]},
  Show[StreamPlot[{1/(x1 - x0), a/(y1 - y0)} (f /. {x -> x0 + u (x1 - x0), y -> y0 + v/a (y1 - y0)}), {u, 0, 1}, {v, 0, a},
     RegionFunction -> Function[{xx, yy}, (rf[[2]] /. {x -> Rescale[xx, {0, 1}, {x0, x1}], y -> Rescale[yy, {0, 1}, {y0, y1}]})],
     opts] /. Arrow[pts_] :> Arrow[({x0, y0} + {x1 - x0, (y1 - y0)/a} #) & /@ pts],
   PlotRange -> {{x0, x1}, {y0, y1}}]]

myStreamPlot[{Sin[2 \[Pi] x], Sin[2 \[Pi] y]}, {x, -1, 1}, {y, -1, 1},
  RegionFunction -> Function[{x, y}, x^2 + y^2 < 1]]

enter image description here

$\endgroup$
1
  • $\begingroup$ Thanks! This works when the {x, y} in RegionFunction match the x and y in {x, -1, 1}, {y, -1, 1}, but I get an error when I use different variables. Also could this be expanded to work with the alternative valid syntax RegionFunction -> (#1^2 + #2^2 < 1 &), which also throws errors? $\endgroup$ – Chris K Mar 15 '19 at 9:11

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.