Phase portrait animations of complex functions

I recently learned about phase portraits through a book titled “Visual Complex Functions: An Introduction with Phase Portraits”. It’s an excellent read so far. I have to apologize in advance for the errors I’m sure I will make here.

I will attempt to give a very casual explanation of phase portraits, show ways to composite complex functions and finally show some of the functions I have played around with. In the appendix I give some details on the tools I used to generate these animations.

Complex numbers can be represented in two ways: a Cartesian and a polar form. The phase of a complex number is the angle φ used in the polar form.

Complex functions are difficult to visualize because there are 4 dimensions to show, as every point in the 2-dimensional plane corresponds to a complex number. Phase portraits aim to simplify this by getting rid of the modulus (|z|) and using colors to visualize phase. These plots still show a lot of valuable information about the function in question. In fact, analytic functions can be reconstructed based only on a phase portrait, up to a positive factor.

Using an HSV color circle, this is what f(z)=z looks like. (The domain in the portraits below will be -2 ≤Re(z), Im(z) ≤2)

We can see that there’s a zero at z=0. If we plot f(z)=1/z we see a very similar result, except we have a pole at z=0. Notice how the order of colors in the portrait is the opposite.

We can add additional zeros and poles by multiplying or dividing the function by (z-P), where P is the location of the zero/pole. Here is f(z)=(z-i)(z+1) for example.

Using higher powers will increase the number of times the whole color map wraps around a zero/pole. This is what f(z)=(z+i)³ looks like. You can see that there are 3 rays for every color.

We can also use other color schemes for these portraits. While displaying less information, using a black-and-white color map can yield quite beautiful results. Here is f(z)=(z-i)(z+2)/(z+i+1) for example.

To extend these portraits to animations, we introduce the parameter t. f(z,t) will be a function that takes a fixed t parameter that’s changing in every frame of the animation. If we animate f(z,t)=(z-t*i) we expect that the zero moves along the imaginary axis. Here’s an HSV animation from t=-2 to 2.

Remember Euler’s identity? Some call it the most beautiful theorem in Mathematics.

In the context of complex numbers we can interpret this as rotating 1 by π resulting in -1. This means that we can use powers of e^i to arbitrarily rotate a zero or pole! Let’s animate f(z,t)=(z-e^(t*i)) from t=0 to 2π.

It’s time to make something pretty! My plan was to have 3 zeros/poles, each one at a relative angle of 2π/3, and a fourth zero in the middle. I wanted to rotate these outer zeros around the origin, but with a larger radius than their modulus, so their “circle of influence” overlaps. I made the speed of rotation different for each zero, by multiplying by N*t. I’m also rotating the zeros around their origin with another multiplication by a power of e. Here are the equations I constructed. Note that no power of e is used for t1(t), because e⁰=1.

Here is a higher quality YouTube video of 2 rotations:

And as a bonus, here is a phase portrait animation of


I used Miniconda to manage all the math related Python packages. I used python-phaseplot to render phase portraits. To render video efficiently I used subprocess and ffmpeg, here is a good explanation. The black-and-white color scheme can be done as follows:

bw_values = (
[(1, 1, 1)] * 8 +
[(0, 0, 0)] * 8)
bw_values = bw_values * 16
cmap = matplotlib.colors.ListedColormap(bw_values)

Any kind of feedback is very welcome, I’m planning on making more of these in the future.