I am trying to plot a vector field on the circle, something like:

enter image description here

Here I have periodic function $f(\theta)$, such that $f(\theta + 2\pi) = f(\theta)$. The arrows on the circle should point in the direction corresponding to the sign of $f(\theta)$. The figure shows a particularly simple example where $f(\theta)$ has a constant sign.

  • $\begingroup$ $f$ is always real-valued? $\endgroup$ Commented Mar 13, 2018 at 16:00
  • $\begingroup$ @J.M. Yes, $f(\theta)$ is always real valued and periodic. You can also assume it is smooth. $\endgroup$
    – a06e
    Commented Mar 13, 2018 at 16:15

2 Answers 2


Here is a start. Define a function that gives you a nice arrow based on position, the direction it should look at and a size. This can be done by transforming the coordinates

arrowHead[p_, dir_, size_] := 
 With[{pts = 
    size*{{-1/4, 0}, {-1/2, -1/3}, {1/2, 0}, {-1/2, 
  Polygon[p + # & /@ pts]

Graphics[arrowHead[{1, 1}, Pi/2, 1]]

Mathematica graphics

The most simple solution is now to create a table of angles where you want to plot the arrows. For each angle you calculate the Sign and use it to calculate the arrow direction. Then draw a circle and over it all the arrows:

f = Sin;
 {Thick, Circle[],
  arrowHead[{Cos[#1], Sin[#1]}, #2, .2] & @@@ 
   Table[{phi, phi + Pi/2*Sign[f[phi]]}, {phi, 0, 2 Pi - Pi/5, Pi/5}]

Mathematica graphics

When the Sign is 0, then the arrows will point outwards.

Depending on your real function f, you might want to consider to analyze the regions of angles, where f has the same Sign. You can then put exactly one arrow directly in the middle. This might be preferable to using a fixed sampling of arrows.

What I mean by that is the following. Assume f to be

f = Sin[#] + 2 Sin[2 #] &
Plot[f[x], {x, 0, 2 Pi}]

Mathematica graphics

If you find the roots of your f, you can create the ranges. For the given f, this can be done by

ranges = Partition[
  Sort[N@Values[Flatten[Solve[f[x] == 0 && 0 <= x <= 2 Pi, x]]]], 2, 1]
(* {{0., 1.82348}, {1.82348, 3.14159}, {3.14159, 4.45971}, {4.45971, 6.28319}} *)

Now we can calculate the middle point inside each range and create a nice colored circle that has only one arrow for each range

inspectRange[f_, {min_, max_}] := 
 Module[{m = Mean[{min, max}], s, col},
  s = Sign[f[m]];
  col = Switch[s, -1, ColorData[96, 1], 1, ColorData[96, 2], _, Black];
  {col, Circle[{0, 0}, 1, {min, max}], 
   arrowHead[{Cos[m], Sin[m]}, m + Pi/2*s, .2]}

Graphics[{Thickness[.02], Circle[], Thickness[.01],
  inspectRange[f, #] & /@ ranges}]

Mathematica graphics

myArrow[θ_, h_] := 
    Arrow[Sign[h] {{Cos[θ], Sin[θ]}, {Cos[θ + .05], Sin[θ + .05]}}]}];

h[θ_] := If[θ < .3, 1, -1];
  myArrow[θ, h[θ]], {θ, 0, 2 π, .2}]]

Mathematica graphics


Your Answer

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

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