is a single-header simple complex number plotting library for the C programming
language. It outputs farbfeld
images from arrays of complex numbers. But also has two convenience functions
to make plotting a breeze, see the code example.
Above is, in order of appearance, the logarithm, the exponential, the
tangent, and the Möbius transform on the unit square.
Complot uses so-called domain coloring to compensate for the fact that
the complex-plane is two-dimensional. It can therefore not be plotted
by standard methods since the domain is two-dimensional as well, which
leaves us with four-dimensions, too much too plot regularly.
Usually one maps the complex argument to the hue of the color and
optionally maps the modulus (absolute value) to saturation and/or value.
For example one could map large absolute values to black and those around
zero to white. Another option is to map the modolus discontinuosly to
the saturation-value space. This is usually done to indicate contour lines,
for example, paint a black strip when you pass every power of e. That is
if x is close to 1, e, e², ..., then map those to a value of zero: black.
Most colorings use a one-to-one map of the argument to the hue. This leaves
us with smooth gradients, which in my opinion make it harder to tell what
is going on. Therefore I have opted to split the the argument into bands
of different hue (see examples below.) I have also decided to go with the
method of painting contour lines instead of turning black/white, this
leaves us with some pretty fractal-like images in some cases.
Here is the ubiquitous exp(1/z) which has an essential singularity at zero.
It is this singularity that makes the argument change "infinitely" close
to zero. Note that the color bands keep changing when the values
get closer to zero. Also note the black bands, as stated above these
indicate growth of the function. On the right-half-plane the function diverges
as z -> 0. But not on the left-half-plane. I think the bands exemplify
clearly the argument changing even at low resolution pictures, this one is
only 256x256 pixels. Compare with the gradient-coloring below.
Below follows a small example that generates the image above.
/* cexpinvplot.c: plots e^(1/z) on the unit square */
#define DIM 256
cexpinv(complex double z)
return cexp(1 / z);
/* plot cexpinv on the unit square to stdout */
complot(cexpinv, DIM, BANDED_CONTOUR, stdout);
cexpinvplot and in a shell redirect its output to
an image of farbfeld format.
Optionally one can of course convert this to png or other formats.
$ ./cexpinvplot > cexpinv.ff
Or directly pipe it through.
$ ff2png < cexpinv.ff > cexpinv.png
$ ./cexpinvplot | ff2png > cexpinv.png
A coloring is defined to be a map from the complex plane into the
red-green-blue color space or even the rgb-alpha space if transparency
is asked for. My coloring with bands and black contour log-bands has
its advantages and has a certain 'soul' to them (just look at the examples!)
But perhaps more canonical is a coloring that is continuous and hence one
that does not have banding. To create such a coloring we remove the banding
above, and map the argument directly to the hue. Then what remains is to
continously map the modulus into the saturation-value space or the
saturation-lightness space. Here one maps white to zero, black to infinity, or
one can switch these (simply pick one.) Usually one fixes the saturation
to the maximum, so then you map the modulus to the value in other words the
absolute value to the value (HA!). Disregarding this, it is more common to work
with lightness rather than value. This is what I have done. Lightness is mapped
to the function x / (1 + x), where x is the square root of the modulus. This
generates the image above.
You can access the four builtin colorings in complot via the fourth argument. Use
RIEMANN to get banded, banded with black contours, smooth,
and the canonical coloring described above, respectively. So for a smooth image
with infinity mapped to black and zero mapped to white, one would call the function
complot(vals, width, height, SMOOTH_RIEMANN, stream);
Here are come comparisons between the banded and smooth colorings.
First of are these gifs that animate z^w where w pass through different
roots of unity. Here the black bands are actually the z's that map z^w
close to modulus one. While the banded version is more interesting it is a bit
jarring to look at.
Secondly, a Blaschke product with 16 random zeroes in the unit square.
One can identify the Zeroes as the points where the color shifts through
the whole spectrum. My favorite is the first picture, banded without
Lastly let's check out the function that takes z to z / (1 - |z|^2), where
|z| is the modulus of z. This maps the unit disk to the complex plane
bijectively and the function is continuous, but it is not comformal (that is
Resources and links
Here are some links that I found useful while making these. I especially
recommend browsing the first.
- Colorful visualization of complex functions
- Domain coloring ~ Wikipedia
- Domain coloring on the riemann sphere ~ Mathematica journal
- farbfeld ~ Suckless