14
$\begingroup$

I want to use StreamPlot to map out the field lines of an electric field $\mathbf{E}$ given by $$ \mathbf{E} = \frac{3D}{4r^{4}}(3\cos(\theta)^{2}-1)\mathbf{\hat{r}} +\frac{3D}{4r^{4}}\sin(2\theta)\boldsymbol{\hat{\theta}} $$ I could convert it to Cartesian coordinates, but I have quite a few more fields to plot, so I would rather leave it in polar coordinates. How can I get StreamPlot to accept polar coordinates?

$\endgroup$
3
  • $\begingroup$ Just use the function! You will get the stream lines in the $r-\theta$ space! $\endgroup$
    – Spawn1701D
    Apr 9, 2013 at 22:10
  • $\begingroup$ possible duplicate with no answers : mathematica.stackexchange.com/questions/18550/… $\endgroup$
    – andre314
    Apr 9, 2013 at 22:11
  • $\begingroup$ Thanks Andre, although the other one was posted first, I've marked it as the duplicate and this one as the canonical version. $\endgroup$
    – Verbeia
    Apr 9, 2013 at 23:05

5 Answers 5

13
$\begingroup$

One way to do it is to write our own wrapper function which does the conversion and feeds it to StreamPlot. Thereby we have the convenience of a selfcontained function without the hassle of having to do the conversion manually every time. We can convert our field

field =  3/(4r^4) (3Cos[\[Theta]]^2-1) Overscript[r, ^]
       + 3/(4r^4) Sin[2\[Theta]] Overscript[\[Theta], ^]

Field

to cartesian form by preparing a set of conversion rules from polar to cartesian coordinates

tocartesian = {Overscript[r, ^] -> x/r Overscript[x, ^] + y/r Overscript[y, ^],
               Overscript[\[Theta], ^] -> -(y/Sqrt[x^2+y^2]) Overscript[x, ^]+x/Sqrt[x^2+y^2] Overscript[y, ^],
               r -> Sqrt[x^2+y^2],
               \[Theta] -> ArcTan[x,y] };

and a rule to make this into a list afterwards

cartesianlist = (a_ Overscript[x, ^] + b_ Overscript[y, ^]) -> {a, b};

Then we can let Mathematica repeatedly apply (//.) our tocartesian rule to eliminate all occurences of r and then let FullSimplify help us to eliminate the trigonometric functions. At last we use cartesianlist to switch to list form:

cartesianfield = FullSimplify[field //. tocartesian] /. cartesianlist

Cartesian form of the field

For convenient usage we define our own PolarStreamPlot function

PolarStreamPlot[{rfield_,thetafield_}, opts___] := Module[
  {tocartesian,cartesianlist,field,cartesianfield},
  tocartesian={Overscript[r, ^]->x/r Overscript[x, ^]+y/r Overscript[y, ^],
               Overscript[\[Theta], ^]->-(y/Sqrt[x^2+y^2])Overscript[x, ^]
                                        + x/Sqrt[x^2+y^2] Overscript[y, ^],
               r->Sqrt[x^2+y^2], \[Theta]->ArcTan[x,y]};
  cartesianlist=(a_ Overscript[x, ^] + b_ Overscript[y, ^])->{a,b};
  field = rfield Overscript[r, ^] + thetafield Overscript[\[Theta], ^];
  cartesianfield = FullSimplify[field//.tocartesian]/.cartesianlist;
  StreamPlot[cartesianfield, opts]
]

and now we can feed it our original $r$-$\theta$ field definition directly

PolarStreamPlot[
  {3/(4r^4) (3Cos[\[Theta]]^2-1),
   3/(4r^4) Sin[2\[Theta]]},
  {x, -3, 3}, {y, -3, 3}
]

StreamPlot

$\endgroup$
2
  • 9
    $\begingroup$ TransformedField["Polar" -> "Cartesian", field, {r, θ} -> {x, y}] will also do the conversion for you, if field = {3/(4 r^4) (3 Cos[θ]^2 - 1), 3/(4 r^4) Sin[2 θ]}. $\endgroup$
    – Michael E2
    Apr 10, 2013 at 1:00
  • $\begingroup$ @MichaelE2 one up for v9!!!! $\endgroup$
    – Spawn1701D
    Apr 10, 2013 at 4:42
15
$\begingroup$

If you have version 9, the TransformedField as mentioned by MichaelE2 is the way to go. In version 8, the analogous thing (which can also still be used in version 9), is this:

Needs["VectorAnalysis`"]
Clear[field, r, θ, ϕ];
m = Transpose[
     Transpose[JacobianMatrix[#, Spherical @@ #]]/
      ScaleFactors[Spherical @@ #]] &@{r, θ, ϕ};
field[r_, θ_, ϕ_] = 
  Simplify[m.{3/(4 r^4) (3 Cos[θ]^2 - 1), 
     3/(4 r^4) Sin[2 θ], 0}];

StreamPlot[
 Delete[
  field @@ CoordinatesFromCartesian[{x, 0, z}, Spherical], 2], 
  {x, -3, 3}, {z, -3, 3}]

stream plot

It uses the VectorAnalysis package like Spawn's answer, but I didn't see any reason why you would first plot the function in polar coordinates, so I inserted the coordinate transformation directly in the StreamPlot. This works for any field defined as a function (field) of the three spherical coordinates, as shown above. All you need is to replace field by field @@ CoordinatesFromCartesian[{x, y, z}, Spherical]. In the plot here, I just set y=0 to get the field lines in the x-z plane.

Edit

The field in the question was given in spherical coordinates, but I copied it from a comment and assumed it was cartesian components. So to correct that, in the definition of field, I added the transformation to the spherical unit vectors. I did this in the most general way I could think of, so that the field can be changed easily. All that you need is the transformation matrix m. If you desire any other coordinate system, just replace Spherical above.

The definition of field also is kept three-dimensional for generality, so that in the StreamPlot I have to Delete one of the three components. Since I'm plotting the x-z plane, I drop the y component which is zero there.

$\endgroup$
3
  • $\begingroup$ The field is given in polar space ($\hat r, \hat\theta$), so first of all you have to change the base of the tangent space. Then you have to consider the transformations involved. For spherical coordinates the change is$$r=\sqrt(x^2+y^2+z^2),\\ \theta=\arccos(z/r),\\ \phi=\arctan(y/x), $$ for cylindrical $$ r=\sqrt(x^2+y^2),\\ \theta=\arctan(y/x),\\ z=z $$ To coincide you have to set z=0 and use the first and the third argument. Cylindrical coordinates are better because they are just the cartesian product of polar space with the Real line. $\endgroup$
    – Spawn1701D
    Apr 10, 2013 at 4:32
  • $\begingroup$ What i did was to first create the stream plot in polar space and then transform the whole plot in cartesian ones. It is evident from your plot that something is wrong though ... Nevertheless v9 comes to the rescue!! $\endgroup$
    – Spawn1701D
    Apr 10, 2013 at 4:34
  • $\begingroup$ Oh yes, I overlooked that part. I'll edit my answer to fix it usng the same method I used here. $\endgroup$
    – Jens
    Apr 10, 2013 at 5:28
11
$\begingroup$

Update - A straightforward alternative

Just to put my comment into code in at least one answer: For V9+,

field = {3/(4 r^4) (3 Cos[θ]^2 - 1), 3/(4 r^4) Sin[2 θ]};
StreamPlot[Evaluate@TransformedField["Polar" -> "Cartesian", 
   field, {r, θ} -> {x, y}], {x, -3, 3}, {y, -3, 3}]
(*  image as above  *)

Original approach

Here is an approach I have been taking with my differential equations class. It shows some of the versatility of the Dt operator and we can break the process down into elementary mathematical steps, instead of using TransformedField as a black box, although using Dt to handle the calculus. We can represent $\mathbf{\hat{r}}$ and $\boldsymbol{\hat{\theta}}$ by Dt[r] and r Dt[θ]. Then straight substitutions may be used. In the end we can convert to a vector field by replacing Dt[x], Dt[y] by {1, 0}, {0, 1} respectively.

polarToCartesian = {r -> Sqrt[x^2 + y^2], θ -> ArcTan[x, y]};
differentialTofield = {Dt[x] -> {1, 0}, Dt[y] -> {0, 1}};

field = (3/(4 r^4) (3 Cos[θ]^2 - 1)) Dt[r] + (3/(4 r^4) Sin[2 θ]) r Dt[θ];

cartesianField = 
 field /. polarToCartesian /. differentialTofield // Simplify
(*
  { (3 x ( 2 x^2 - 3 y^2)) / (4 (x^2 + y^2)^(7/2)),
   -(3 y (-4 x^2 +   y^2)) / (4 (x^2 + y^2)^(7/2))}
*)

StreamPlot[
 cartesianField,
 {x, -3, 3}, {y, -3, 3}
 ]

Mathematica graphics


$\endgroup$
4
$\begingroup$

Ok the stream plot on the polar space is given by say

With[{D=1},plot=StreamPlot[{3*D/(4r^4)(3Cos[θ]^2-1),3*D/(4r^4) Sin[2θ]},{r,0,1},{θ,0,2*π},
     StreamScale -> {Automatic, Automatic, Automatic, Function[{x, y, vx, vy, n}, x]}]]

Now, IF you want this stream plot embedded on cartesian space you can either transform the vector field to cartesian space as you correctly say or do the following:

Needs["VectorAnalysis`"]
Show[plot/.
Arrow[v:{__?VectorQ}]:>Arrow[(Most[CoordinatesToCartesian[Append[#, 0], Cylindrical]]&/@v)], 
PlotRange -> Automatic]

I suppose your question is if there is a function like PolarPlot for StreamPlot or other plot functions. The short answer is no. You can either change before hand the function or the field or embed the field afterward. Which method is best depends on the specific trasformation involved and if you want to exploit Mathematica's routines in giving you the best presentation of the field.

$\endgroup$
2
  • $\begingroup$ It works (+1), but I had to correct a small syntax error in StreamScale where a } is missing. $\endgroup$
    – Jens
    Apr 10, 2013 at 5:43
  • $\begingroup$ @Jens thanx! I am correcting it now! $\endgroup$
    – Spawn1701D
    Apr 10, 2013 at 5:51
4
$\begingroup$

For those using Mathematica 9, I have created the following function to produce polar plots. It takes all options that can be given to StreamPlot, but also masks any results outside of the provided domain (which is provided in polar coordinates).

SetAttributes[PolarStreamPlot, HoldAll];
PolarStreamPlot[
  fns_, {r_Symbol, rMin_, rMax_}, {t_Symbol, tMin_, tMax_}, opts___] :=
  Module[{Fns, x, y, RF, TMin, TMax, mArcTan, RMax},
  If[rMin >= rMax,
   Throw["Invalid range for r!"]
   ];
  If[tMin >= tMax || tMax - tMin > 2 Pi,
   Throw["Invalid range for \[Theta]!"]
   ];
  TMin = Mod[tMin, 2 Pi, tMin];
  TMax = Mod[tMax, 2 Pi, tMin];
  If[TMax == TMin, TMax += 2 Pi];
  mArcTan[vars__] = Mod[ArcTan[vars], 2 Pi, TMin];
  Fns = TransformedField["Polar" -> "Cartesian", 
     fns, {r, t} -> {x, y}] /. ArcTan -> mArcTan;
  RMax = rMax;
  StreamPlot[Fns, {x, -RMax, RMax}, {y, -RMax, RMax}, 
   RegionFunction -> 
    Function[{x, y}, 
     Evaluate[
      mArcTan[x, y] <= TMax && rMin <= Sqrt[x^2 + y^2] <= rMax]], opts]
  ]

Hope this helps!

$\endgroup$
8
  • $\begingroup$ You can consider using Block to localize r and t so the function will still work when these have a value. Also, you can use Message and Return instead of Throw. An uncaught Throw is technically a runtime error. Finally, Evaluate only works when it's at level 1 within a held function. I'm not sure it's necessary here. $\endgroup$
    – Szabolcs
    Feb 10, 2014 at 19:53
  • $\begingroup$ To force a single evaluation of rMax, use an additional Module variable, say rMax2 and assign rMax2 = rMax. Then use rMax2 in StreamPlot. $\endgroup$
    – Szabolcs
    Feb 10, 2014 at 19:58
  • $\begingroup$ @Szabolcs With regard to putting r and t in a Block, isn't this already happening since they're arguments of the function? (Sorry, I'm a CS guy - not so used to Mathematica) $\endgroup$
    – s.pledger
    Feb 10, 2014 at 21:36
  • $\begingroup$ There's the line starting with Fns = .... It has {r,t}. This will effectively evaluate the symbols that were passed to PolarStreamPlot as $r$ and $t$. If they have values, it will cause an error in TransformedField. Try setting r=1 then calling PolarStreamPlot[..., {r, ...}, ...]. It will show errors. However, if you wrap the whole thing in Block[{r,t}, ...] then it'll work. Do not mind about the red colouring you see, it's just a warning. But doing this here is justified. $\endgroup$
    – Szabolcs
    Feb 10, 2014 at 21:47
  • $\begingroup$ Another potential localization failure is not using := in the definition of mArcTan. However, for reasons that I don't understand, Mathematica does rename vars to localize it, so having a globally defined vars=1 does not actually break things. $\endgroup$
    – Szabolcs
    Feb 10, 2014 at 21:51

Your Answer

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

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