The other day I came across this fantastic video on the veritassium youtube channel. It describes a mathematical treasure called the logistic map – a chaotic sequence that emerges from a simple formula. Visualizing it reveals detailed fractal images. In this post I’ll share some visualizations I made using p5.js which illustrate it.

Disclaimer: I’m not a mathematician by trade, so if you are, please don’t hesitate to email me with corrections or suggestions.

To explain what the logistic map is, I’ll borrow an analogy from the video linked above. Imagine we want a formula to predict the population of a group of animals over time. A very simple one could be `nextYear = thisYear * rate`, where `rate` is some fertility rate. Given any `rate` above 1.0, though, the numbers will increase exponentially towards infinity.

That’s not very realistic, so let’s also multiply the result by `(1 - thisYear)` each time. This creates a feedback loop, keeping the population from exploding. For `rate`s near 1.0, the population stabilizes quickly for any starting value of `thisYear`.

Here’s an interactive graph that shows the output of this equation. Adjust the starting population and rate (`r`) using the sliders below. Notice that the starting value has little effect on the long-term shape of the graph. However, increasing the `r` value has very interesting effects.

Starting Population Rate r

When `r` gets up to about 3, a cycle appears. There are two phases – the population bounces between two values. When `r` exceeds about 3.5, the graph shows a 4-phase cycle. I find this behavior fascinating and unintuitive. How does this simple feedback loop create such complex patterns?

The number of phases keeps doubling as `r` grows, eventually cascading into chaos. In this visualization it appears completely random but we can use another type of visualization to show some order hidden within.

We can draw this in another way by running the “population model” described above with many different `r` values and plotting where the cycles appear. In the graph below, the x axis is `r` from 0 to 4.0. For each value of `r`, we run many random starting `y` values through a `y = y * r * (y - 1)` function 100 times and then plot the point `(r, y)`. The resulting image shows the regular “bifurcation” of the series.

Click and drag on the diagram to zoom in.

Notice the fractal nature of the graph. The upper “arm” of each split is a smaller copy of it’s parent. This is very surprising! Even crazier, the distance between each bifurcation is always relative to a constant value (about 4.669201).

This number is one of the fundamental, physical constants of nature and appears often in places we wouldn’t expect, similar to π and e. This one is called a Feigenbaum constant, which, also like π or e, is irrational.

It turns out that this series is closely related to another famous fractal, the Mandelbrot set. The Mandelbrot set is the set of complex numbers `c` where the function `f(z) = z^2 + c` does not diverge. If we take that definition and remove the “complex number” part, we are left with `f(x) = x^2 + y`, where `y` is a real number. In a way, this logistic map contains the “non-complex” half of the Mandelbrot set. In other words, this logistic map provides the values along another dimension of the “spine” of the Mandelbrot set.

As you move along the center line (the “spine”) of the Mandlebrot set, you’ll encounter a new bulb each time the diagram bifurcates. For higher values of `y`, the bifurcation diagram exhibits a lot of noisy chaotic values, but we can see areas of relative calm where the values converge on a few points before returning to chaos. Zoom into those area to see that they correspond with more self-similar copies of the entire set.

It’s easier to understand this relationship visually, so here’s another interactive diagram.

Click and drag on the diagram to zoom in.

Just like the Mandelbrot set, the logistic map seems like a gold mine of fractal beauty. Using it as a building block for algorithmic art leads to all sorts of variations.

This one uses the formula from the first example, `y = r * y * (1-y)`. Instead of increasing `r` along the x axis, it uses 2 different configurable starting values (`m` and `n`) and increments them by a fixed amount. At each step, both of these are run through the logistic map, drawing a circle centered at `(x,y)` where `x` is the number of total steps taken and `y` is `logisticMap(m)`. The radius of the circle is `sin(n)`.

Explore some different values and find some interesting combinations!

Some other resources about the logistic map I found while researching this post: