Julia Sets

from Essential Mathematica for Students of Science
© James J. Kelly, 1998
Last revised: January, 2006

Introduction

Terminology

Julia sets characterize the behavior of iterated function systems of the form z → f[z, c] where z is a point in the complex plane, f is a nonlinear mapping function, and c is a complex parameter.  Let (Subscript[f, n])[z, c] represent the (n^th) iteration of the mapping function, such that (Subscript[f, n])[z, c] = f[(Subscript[f, n - 1])[z, c], c].  The sequence of points {z,  (Subscript[f, 1])[z, c],  
      (Subscript[f, 2])[z, c],  ⋯} is called the orbit of z.  We can classify these orbits as follows.

a) A fixed point is mapped onto itself, such that z = f[z, c].  A fixed point is further classified as stable if nearby points approach the fixed point or as unstable if nearby points recede upon iteration of the mapping.  A fixed point is considered neutrally stable or indifferent if nearby points orbit at fixed distance as the map is iterated.

b) Points for which \(TraditionalForm\`|z| -> ∞\) are said to escape to infinity.

c) A stable cycle or orbit is a set of points which recur after n iterations, such that z = (Subscript[f, n])[z, c].  The cycle is periodic if n is finite, nonperiodic or chaotic if n is infinite but the iteration is confined to a limited region.  Each member of a periodic cycle of order n is a fixed point of the transformation (Subscript[f, n])[z, c].

d) A stable fixed point or orbit has a basin of attraction or prisoner set consisting of all points which are attracted to that orbit upon iteration.

The filled Julia set (Subscript[K, c]) for f[z, c] consists of all points z which are confined to finite |z|, while the proper Julia set (Subscript[J, c]) is the set of points on the border of (Subscript[K, c]) between stable and unstable orbits.  Technically, Julia sets contain only the points on the boundary separating points which are trapped from points which escape, viz. the neutrally stable points.  However, it is often easier to compute and display a filled Julia set than a true Julia set and it has become common usage to refer to filled Julia sets simply as Julia sets. Filled Julia sets are described as connected if there exists a continuous path between all pairs of points in the set, and as disconnected otherwise.  For some filled Julia sets there are no interior points, so that the filled Julia set degenerates to the proper Julia set.  If a Julia set without interior points is connected, it is often described as dendritic because it then consists of jagged paths that usually have many branches.  A disconnected Julia set without interior points (or with very small enclosed areas) is often described as fractal dust.

During World War I, French mathematicians Gaston Julia and Pierre Fatou studied the properties of iterated function systems, particularly rational mappings of the complex plane, and proved a very important theorem that states that the entire boundary of a stable region can be generated from any arbitrarily small segment of that boundary in a finite number of iterations.  This important property of Julia sets is now known as self-similarity, but was largely forgotten for about 60 years until Benoit Mandelbrot used computers to generate fascinating displays of these sets and the intricate structure of their boundaries.  Mandelbrot coined the term fractal to describe such boundaries and compared them to coastlines.

Relationship between Mandelbrot and Julia sets

The most famous Julia sets are those belonging to the quadratic map z -> (z^2) + c and are closely related to the Mandelbrot set.  The Mandelbrot set consists of all parameters c for which the point (Subscript[z, 0]) = 0 is trapped by the quadratic map, while the Julia set for map parameter c consists of the points z which are trapped by the map.  Thus, the Mandelbrot set is displayed in the complex c-plane while Julia sets are displayed in the complex z-plane.  It has been demonstrated that the Mandelbrot set provides a system for classifying the properties of a Julia set.  Parameters c contained within the Mandelbrot set produce Julia sets which are connected, whereas parameters outside the Mandelbrot set produce disconnected Julia sets.  Thus, the boundary of the Mandelbrot set marks the transition between these two types of Julia sets.  Furthermore, each bud of the Mandelbrot set corresponds to a periodic cycle.

In this notebook we illustrate the relationship between the Mandelbrot set and Julia sets derived therefrom.  Julia sets for other maps are suggested in the exercises.

Escape Time Algorithm

Many algorithms have been developed to display Julia sets, some of which are described in the references below.  The best choice of algorithm often depends upon the properties of the particular Julia set under investigation, while the optimum method of rendering a graphical display is often a matter of artistic taste.  In this notebook we employ the escape time algorithm, in which the number of iterations needed for an orbit to move outside a threshold radius that guarantees escape is displayed as a function of the initial point (Subscript[z, 0]).  For the quadratic map one can show that this threshold radius is Max[|c|, 
        2].  The escape time algorithm is well suited for displaying connected Julia sets with substantial enclosed area in the form of density plots using either color or gray level to gauge the escape time.  However, because the rendering of a density plot can be very slow, it is more efficient for dendritic sets to select and display only those points which remain trapped after some specified number of iterations in the form of a list plot.  Another algorithm particularly well suited to dendritic sets is the inverse iteration method presented in JuliaIIM.nb.  Neither of these methods works well for disconnected sets, which typically require very long computation times with the quality of the graphical display highly dependent upon the mesh size and iteration limits.  The books authored or edited by Peitgen include many breathtaking figures of far greater clarity than we can produce in reasonable time using Mathematica implementations of these algorithms on a PC; although Mathematica can help one to explore the basics, high-quality computer art still requires programs written in a compiled language running on faster hardware.  Nevertheless, you will probably find these examples amusing and may be inspired to investigate or create more efficient algorithms.

Notes on rendering graphics

For the escape time algorithm we employ a uniform grid covering the relevant range of the complex plane and at each grid point iterate the mapping function until the iterated point moves beyond some large radius or until an iteration limit is reached.  A graphical display is then made by assigning a gray level or color to each grid point based upon its escape time.  When the iteration limit is large, it can be useful to reduce the contrast by plotting the logarithm of the escape time instead of the raw escape time itself.  Periodic functions of escape time, perhaps combined with logarithmic functions, also produce pleasing results.

If the grid spacing is too coarse or the iteration limit too small, one might get the erroneous impression that a disconnected set is connected, but decreasing the grid spacing or increasing the iteration limit rapidly inflates the computation time required to construct the escape rate data.  Given that the Julia set consists of points which remain trapped while nearby points escape slowly, the iteration limit tends to govern the sharpness with which boundaries can be determined.  Therefore, for initial explorations it is often a good strategy to employ a large iteration limit but a coarse grid.

Rendering a density plot often requires much more time than construction of the data themselves, especially for fine grids.  Artistic coloring functions can provide very pleasing effects, but require much more memory and produce much larger notebook files than gray-level graphics.  Furthermore, gray-level often provides sharper images.  Therefore, most figures displayed here will be made using gray level, but the reader is invited to exercise artistic creativity in the choice of color functions.  Of course, such experiments should be made with smaller data sets first!

References

G. Julia, Sur l'iteration des fonctoins rationnelles, Journal de Math Pure et Appl 8, 47 (1918).

P. Fatou, Sur les équations fonctionelles, Bull Soc Math Fr 47, 161 (1919); ibid., 48, 33 (1920).

B. Mandelbrot, The Fractal Geometry of Nature, (Freeman, San Francisco, 1982).

H.-O. Peitgen and P.H. Richter, The Beauty of Fractals, (Springer-Verlag, Berlin, 1986).

The Science of Fractal Images, edited by H.-O. Peitgen and D. Saupe, (Springer-Verlag, Berlin, 1988).

H.-O.Peitgen, H. Jürgens, and D. Saupe, Chaos and Fractals — New Frontiers of Science, (Springer-Verlag, N.Y. 1992).

Initialization

Defaults and packages

ClearAll["Global`*"];
Off[General::spell,  General::spell1];
$TextStyle = {FontFamily -> "Times", 
          FontSize -> 12};

Needs["Graphics`"]

Manipulation of complex numbers

\(\(\(conjugate::usage\  = "A simple method for computing the conjugate of an object which is explicitly complex.";\)\(
\)
    \)\)
conjugateRule  =  
        Complex[re_, im_] :> Complex[re, -im];
conjugate[exp__] :=  exp /. conjugateRule;

The following rules convert complex numbers to {x, y} pairs.

ComplexToArgand = {Complex[x_, y_] -> {x, y}, 
          x_Real -> {x, 0}, x_Integer -> {x, 0}};

The following function converts a list of complex numbers to a Point object suitable for plotting.

ComplexToPoint[cpt_Complex] := Point[{Re[cpt], Im[cpt]}];
ComplexToPoint[cpt_List] := Point[{Re[#], Im[#]}] & /@ 
        cpt

Mandelbrot set

Escape Time Algorithm

\(\(\(Clear[MandelbrotRate];\)\(
\)
    \)\)
\(\(\(MandelbrotRate::usage\  = \ \*""MandelbrotRate[cx,cy,nmax] computes the escape rate for c = cx + I cy under the quadratic map z->\!\(z\^2\)+c beginning with z=0.  The maximum number of iterations is given by nmax, which must be an integer."";\)\(
\)
    \)\)
\(\(MandelbrotRate\  = \ 
        Compile[{cx, 
            cy, {nmax, \ _Integer}}, 
Module[{c, z, 
              ct = 0}, 
 (*\ 
              define\ point\ in\ complex\ plane\ *) 
c = 
              cx\  + \ I\ cy; 
 (*\ 
              initialize\ map\ *) 
z\  = \ c; 
 (*\ 
              iterate\ quadratic\ map\ until\ z\ reaches\ escape\ radius\ or\ iteration\ limit\ is\ reached\ *) 
While[\((Abs[z] < 
                    2)\)\  && \ \((ct ≤ nmax)\), \(++ct\); 
              z\  = \ z*z + \ c;]; 
 (*\ 
              return\ iteration\ counter\ *) 
ct]\ ];\)\)

Images

Entire Mandelbrot set

samples = {{0.2, 0.3}, {-0.745429, 0.113008}, {-1.25, 
            0.0}, {0.11031, -0.67037}, {0. , 1. }};

MandelbrotData  =  
        Table[MandelbrotRate[cx, cy, 1000], {cy, -1.2, 1.2, 
            0.005}, {cx, -2, 0.6, 0.005}];

MandelPlot = 
        ListDensityPlot[MandelbrotData, Frame -> False, 
          Mesh -> False, AspectRatio -> Automatic, 
          MeshRange -> {{-2.0, 0.6}, {-1.2, 1.2}}, 
          ColorFunction -> (GrayLevel[Mod[Log[0.01 + #], 1]] &), 
          DisplayFunction -> Identity];

\(\(Show[{MandelPlot, 
          MultipleListPlot[samples, SymbolStyle -> RGBColor[1, 0, 0], 
            SymbolLabel -> {{"a", "b", "c", "d", "e"}}, DisplayFunction -> Identity]}, 
        DisplayFunction -> $DisplayFunction];\)\)

Seahorse valley

The region near the junction between the two largest buds has been dubbed seahorse valley because magnification reveals structure resembling an aquatic herd.

MandelbrotData2  = 
        Table[MandelbrotRate[cx, cy, 1000], {cy, 0. , 0.2, 
            0.0005}, {cx, -0.8, -0.7, 0.0005}];

ListDensityPlot[MandelbrotData2, Frame -> False, 
        Mesh -> False, AspectRatio -> Automatic, 
        MeshRange -> {{-0.8, -0.7}, {0.0, 0.2}}, 
        ColorFunction -> (GrayLevel[
                Mod[Log[0.01 + #], 1]] &)];

Self-similarity

Further magnification reveals yet more detailed structure containing innumerable miniscule buds which each resemble the primary bud for the entire set.  The appearance of structure at arbitrarily fine scales that it is qualitatively similar to that observed at larger scales is a phenomenon described as self-similarity.

MandelbrotData3  =  
        Table[MandelbrotRate[cx, cy, 1000], {cy, 0.163, 0.166, 
            0.000005}, {cx, -0.749, -0.745, 
            0.000005}];

ListDensityPlot[MandelbrotData3, Frame -> False, 
        Mesh -> False, AspectRatio -> Automatic, 
        MeshRange -> {{-0.749, -0.745}, {0.163, 0.166}}, 
        ColorFunction -> (GrayLevel[
                Mod[Log[#], 1]] &)];

Julia sets for the quadratic map

Function definitions

Escape time algorithm

\(\(\(Clear[JuliaRate];\)\(
\)
    \)\)
\(\(\(JuliaRate::usage\  = \ \*""JuliaRate[zx,zy,cx,cy,nmax] computes the number of iterations for the quadratic map z->(z^2)+c for which z = zx + I zy remains within radius rmax=Max[|c|,2] where c = cx +I cy is the complex parameter characterizing the map.  The maximum number of iterations is given by nmax, which must be an integer."";\)\(
\)
    \)\)
\(\(JuliaRate\  = \ 
        Compile[{zx, zy, cx, cy, {nmax, \ _Integer}}, \ 
          Module[{c, z, ct = 0, rmax}, 
 (*\ 
              define\ map\ parameter\ and\ point\ position\ *) 
c = \ cx\  + I\ cy; z = \ zx\  + \ I\ zy; 
            rmax = Max[Abs[c], 2]; 
 (*\ 
              iterate\ quadratic\ map\ until\ Abs[
                  z]\ exceeds\ rmax\ or\ the\ iteration\ limit\ is\ reached\ *) 
While[\((Abs[z] < rmax)\)\  && \ \((ct ≤ 
                    nmax)\), \(++ct\); z\  = \ z*z + \ c;]; 
            ct]\ ];\)\)

plotJulia[JuliaData_, opts___Rule] := 
      ListDensityPlot[JuliaData,  opts, Mesh -> False, 
        Frame -> False, AspectRatio -> Automatic]

Periodic points

The following function locates the fixed points for the (n^th) iteration of f for a particular parameter c

fixedPoints[f_, n_, c_] := 
      Module[{sol, λ, g}, 
        g[z_] = Nest[f[c, #] &, z, n]; λ[z_] = 
          D[g[t], t] /. t -> z; 
        sol = Solve[g[z] == z, 
            z]; {#, λ[#]} & /@ (z /. sol)]

while

cycle[f_, n_, c_] := 
      First /@ Select[fixedPoints[f, n, c], 
          Abs[#1[[2]]] ≤ 
              1 &]

selects periodic points constituting a stable n-cycle.  However, it is probably necessary to test high-order (n ≳ 6) cycles for possible truncation errors.

Characteristic Julia sets for selected Mandelbrot points

The main body

Parameters drawn from the main body of the Mandelbrot set yield connected Julia sets which may be described as deformed circles that represent the basin of attraction for a stable fixed point contained within.  The Julia set below belongs to the Mandelbrot point labelled a and has a fixed point.

a = 0.2 + 0.3  I;
fp = cycle[#1 + #(2^2) &, 1, a]

The following figure displays the basin of attraction for this fixed point as white.  With only one fixed point, this basin is also the filled Julia set; the proper Julia set is the boundary between light and darkness.

The following figure displays the basin of attraction for this fixed point as white.  With only one fixed point, this basin is also the filled Julia set; the proper Julia set is the boundary between light and darkness.

\(\(\(\(Clear[JuliaData];\)

    \(JuliaData = \ 
        Table[JuliaRate[x, y, 0.2, 0.3, 1000], {y, \(-1.5\), 1.5, 
            0.01}, {x, \(-1.5\), 1.5, 0.01}];\)\)\(\ \)\)\)

DisplayTogether[
        plotJulia[JuliaData, 
          MeshRange -> {{-1.5, 1.5}, {-1.5, 1.5}}], 
        Graphics[ComplexToPoint[fp]], 
        Prolog -> PointSize[0.02]];

The following function can be used to show that points within the basin of attraction eventually settle upon the fixed point and that those outside diverge.

\(ShowOrbit[c_, point_, iterations_, opts___] := 
      Module[{orbit}, 
orbit = \ 
          NestList[#\^2 + c &, point, iterations] /. 
            ComplexToArgand; 
ListPlot[orbit, opts, 
          PlotJoined -> True, PlotRange -> All, 
          AspectRatio -> Automatic]]\)

For example, the following plots show that the fates of two points separated by as little as 0.001 i can be completely different.

ShowOrbit[a, 0.8 - 0.787  I, 30];

ShowOrbit[a, 0.8 - 0.788  I, 16, 
        Epilog -> Circle[{0, 0}, 2]];

It may take a long time to capture a member of the prisoner set,

\(FixedPoint[#\^2 + a &, 0.8 - 0.787  I]\)

but a point outside the basin of attraction escapes rapidly once its orbit takes it far enough from the fixed point, even if it appears to dawdle nearby for a while.

The region between the main body and the largest bud

The Julia set below belongs to the Mandelbrot point labelled b, which is located in seahorse valley close to the main bud.  Although the Julia set is disconnected, it remains fairly dense because it is close to the boundary between connected and disconnected sets.  If the grid spacing is too coarse or the iteration limit too small, one might get the erroneous impression that such a set is connected, but decreasing the grid spacing or increasing the iteration limit rapidly inflates the computation time required to construct the escape rate data.  Furthermore, rendering a colorful display often requires more time than construction of the data themselves.  Given that the Julia set consists of points which remain trapped while nearby points escape slowly, the iteration limit tends to govern the sharpness with which boundaries can be determined.  Therefore, for initial explorations it is often a good strategy to employ a large iteration limit but a coarse grid.

\(\(\(\(Clear[JuliaData];\)

    \(JuliaData = 
        Table[JuliaRate[x, y, \(-0.745429\), 0.113008, 100000], {y, \(-0.9\), 
            0.9, 0.01}, {x, \(-1.55\), 1.55, 0.01}];\)\)\(\ \)\)\)

plotJulia[JuliaData];

The addition of color can also be fun and the construction of a color function provides opportunity for artistic creativity.

plotJulia[JuliaData, 
        ColorFunction -> (Hue[Sin[Sqrt[#]]] &)];

The following version provides a more accurate impression of the very complex structure of this set but costs much more time, especially for rendering the graphics.

\(\(\(\(Clear[JuliaData];\)

    \(JuliaData = 
        Table[JuliaRate[x, y, \(-0.745429\), 0.113008, 100000], {y, \(-0.9\), 
            0.9, 0.002}, {x, \(-1.55\), 1.55, 0.002}];\)\)\(\ \)\)\)

plotJulia[JuliaData, 
        MeshRange -> {{-1.55, 1.55}, {-0.9, 0.9}}];

A point between two buds

The Julia set below belongs to the Mandelbrot point labelled c at the border between the second and third main buds along the real axis.  In this region there is transition between 2-cycles

cycle2 = cycle[#1 + #(2^2) &, 2, -1.249]

and 4-cycles

cycle[#1 + #(2^2) &, 4, -1.251]

where the fixed points of the second bud bifurcate as the third bud is entered.

\(\(\(\(Clear[JuliaData];\)

    \(JuliaData = 
        Table[JuliaRate[x, y, \(-1.25\), 0.0, 1000], {y, \(-1\), 1, 
            0.005}, {x, \(-2\), 2, 0.005}];\)\)\(\ \)\)\)

DisplayTogether[
        plotJulia[JuliaData, MeshRange -> {{-2, 2}, {-1, 1}}], 
        Graphics[ComplexToPoint[cycle2]], 
        Prolog -> PointSize[0.02]];

It is interesting to observe that even though this Julia set appears to be symmetric across both the real and imaginary axes, the critical points do not share that symmetry.  Nevertheless, the orbits for points within the basin of attraction eventually settle upon this 2-cycle.

cycle2 = cycle[#1 + #(2^2) &, 2, -1.2]

\(Drop[NestList[#\^2 - 1.2 &, \(-0.3\) I, 130], 
      110]\)

However, this can take a long time near the transition between 2-cycle and 4-cycle.

Fatou dust

The Julia set below belongs to the Mandelbrot point labelled d.

\(\(\(\(Clear[JuliaData];\)

    \(JuliaData = 
        Table[JuliaRate[x, y, 0.11031, \(-0.67037\), 1000], {y, \(-1.5\), 
            1.5, 0.005}, {x, \(-1.5\), 1.5, 0.005}];\)\)\(\ \)\)\)

plotJulia[JuliaData];

Dendrite

The Mandelbrot point labelled e produces a connected but very thin Julia set, a dendrite.

\(\(\(\(Clear[JuliaData];\)

    \(JuliaData = 
        Table[JuliaRate[x, y, 0. , 1. , 1000], {y, \(-1.5\), 1.5, 
            0.005}, {x, \(-1.5\), 1.5, 0.005}];\)\)\(\ \)\)\)

plotJulia[JuliaData];

Although this display suggests a thin set, the fact that nearby points escape very slowly tends to artificially inflate the width of the set obtained using the escape time algorithm.  In fact, one can prove that this Julia sets has no enclosed points — it is a dendrite without width.  A more accurate picture can be obtained by displaying only relatively long times.

ListPlot[Position[JuliaData, x_ /; x > 20], Axes -> False, 
        AspectRatio -> Automatic];

The inverse iteration method provides a better algorithm for dendritic Julia sets, as shown in JuliaIIM.nb.

Relationship between Julia and Mandelbrot sets

The fixed points for the quadratic map f[z] = (z^2) + c are

eq1 = (z^2) + c == z;
fp = z /. Solve[eq1, z]

and the eigenvalues are λ = (f^′)[(Subscript[z, fp])] = 
          2  (Subscript[z, fp]):

λ = 2  fp

A fixed point is attractive if |λ| < 
        1, indifferent if |λ| = 
        1, or repelling if |λ| > 
        1.  Thus, for this mapping we obtain an attractive fixed point for those parameters c for which |(Subscript[z, fp])| < 
        (1/2) is found within disk of radius (1/2).  For real values of c it is clear that the second fixed points is always unstable or repelling, while the other is attractive for the open interval -(3/4) < c < (1/4).  To determine the locus of complex c for which |λ| = 
        1, we substitute

temp = 
      ExpToTrig[eq1 /. 
            Equal -> Subtract /. {z -> 
              (1/2) (E^(I ϕ)), 
            c -> x + I y}]

and produce a parametric representation of the real and imaginary parts of c

eq2 = 
      Simplify[{Re[temp] == 0, 
          Im[temp] == 0}, (x | y | ϕ) ∈ 
          Reals]

curve = {x, 
          y} /. Solve[
            eq2, {x, 
              y}][[1]]

plot1 = 
        ParametricPlot[Evaluate[curve], {ϕ, 0, 2  π}, 
          AspectRatio -> Automatic];

Therefore, the main body of the Mandelbrot set contains parameters c for which the mapping z -> (z^2) + c possesses one attractive fixed point in the disk |(Subscript[z, fp])| < 
        (1/2).  The cardioid outline of the main body consists of those c for which the fixed points become neutrally stable with |λ| = 
        1.

A cycle of period 2 consists of the attractive fixed points of the iterated mapping

\(f\_2[z] = Nest[#\^2 + c &, z, 2]\)

The 4 fixed points of the quartic map

sol2 = Solve[(Subscript[f, 2])[z] == z, z]

contain the fixed points of the original map plus two new points.  The new points and the original points are stable in nonoverlapping domains.  To determine the region of stability for the 2-cycle, we examine the eigenvalues

(Subscript[λ, 2]) = D[(Subscript[f, 2])[z], z] /. sol2 // Simplify

and find that both members of the 2-cycle have the same eigenvalue.  The 2-cycle is stable for |1 + c| < 
        (1/4), which is clearly a disk of radius (1/4) centered upon -1.  At c = -(3/4) the boundaries of basins of attraction for the n = 1 and n = 2 fixed points are tangent and the stable fixed points are degenerate.  Thus, if one is moving along the real axis from the main body into the next largest bud, one finds that the fixed point is stable in the main body, neutral at the point of tangency, and unstable thereafter.  Similarly, the periodic points for n = 2 evolve from unstable to stable.  In effect, the n = 1 fixed point bifurcates at the transition into the n = 2 basin.  This behavior should be very reminiscent of the logistic map, except that this quadratic map is extended into the complex plane.

(Subscript[λ, 2]) /. {c -> -(3/4)}

Plot[Evaluate[Abs[(Subscript[λ, 2])]], {c, -2, 2}, 
        PlotRange -> {All, {0, 2}}, 
        PlotStyle -> {RGBColor[1, 0, 0], RGBColor[1, 0, 0], 
            RGBColor[0, 1, 0], RGBColor[0, 0, 1]}];

The analysis can be continued along the real axis, where the complex quadratic map is equivalent to the logistic map, but becomes cumbersome as the polynomial order increases.  However, having analyzed the logistic equation in considerable detail, we already know that to expect pitchfork bifurcations with increasing frequency until the chaotic regime is reached.  The reappearance of a miniature version of the main body near c ≈ -1.75 corresponds to the narrow window of order that interrupts the general chaos of the logistic map for large μ.  Therefore, we need not analyze the real axis any further at this time.

More interesting behavior is obtained for buds attached to the main body for complex c, but because the analysis is too difficult to reproduce here we simply describe some of the main results.  Recall that the main cardioid was parametrized in terms of the angle ϕ.  It is useful to define α = ϕ/2  π.  The nature of the Julia set depends critically upon the nature of α.  If α is rational and is expressed in irreducible form as α = k/n, a secondary bud sprouts from the main cardioid body that governs attractive orbits of period n.  Thus, there are one 2-cycle, two three cycles, two 4-cycles, four 5-cycles, etc.  The following function produces a list of attachment points for n-cycles.

buds[n_] := 
      Transpose[
        curve /. {ϕ -> π Cases[
                  Range[(2/n), 2, (2/n)], _Rational]}]

The colored dots in the following figure tag buds according to period.  Each of these buds generate a similar family of offspring, according to the principle of self-similarity.

Show[{MandelPlot, Graphics[AbsolutePointSize[3]], 
          Graphics[RGBColor[1, 0, 1]], Graphics[Point /@ buds[6]], 
          Graphics[RGBColor[0, 0, 1]], Graphics[Point /@ buds[5]], 
          Graphics[RGBColor[0, 1, 0]], Graphics[Point /@ buds[4]], 
          Graphics[RGBColor[1, 0, 0]], Graphics[Point /@ buds[3]]}, 
        DisplayFunction -> $DisplayFunction];

The nature of Julia sets for irrational α is not as well understood and is an active field of inquiry that will not be pursued here; this author is not expert in this subject.  The reader is encouraged to consult the original literature.