All of the site favicons that I use have been generated by contour plots of the complex logarithm and complex exponential functions.

Experiments

HSV | Viridis | Cividis | Inferno | Jet | Magma | Plasma | Rainbow | Turbo

Real

/code/icons/complex-ln/outputs/hsv/real_part.svg /code/icons/complex-ln/outputs/viridis/real_part.svg /code/icons/complex-ln/outputs/cividis/real_part.svg /code/icons/complex-ln/outputs/inferno/real_part.svg /code/icons/complex-ln/outputs/jet/real_part.svg /code/icons/complex-ln/outputs/magma/real_part.svg /code/icons/complex-ln/outputs/plasma/real_part.svg /code/icons/complex-ln/outputs/rainbow/real_part.svg /code/icons/complex-ln/outputs/turbo/real_part.svg

Imaginary

/code/icons/complex-ln/outputs/hsv/imag_part.svg /code/icons/complex-ln/outputs/viridis/imag_part.svg /code/icons/complex-ln/outputs/cividis/imag_part.svg /code/icons/complex-ln/outputs/inferno/imag_part.svg /code/icons/complex-ln/outputs/jet/imag_part.svg /code/icons/complex-ln/outputs/magma/imag_part.svg /code/icons/complex-ln/outputs/plasma/imag_part.svg /code/icons/complex-ln/outputs/rainbow/imag_part.svg /code/icons/complex-ln/outputs/turbo/imag_part.svg

Absolute

/code/icons/complex-ln/outputs/hsv/abs_part.svg /code/icons/complex-ln/outputs/viridis/abs_part.svg /code/icons/complex-ln/outputs/cividis/abs_part.svg /code/icons/complex-ln/outputs/inferno/abs_part.svg /code/icons/complex-ln/outputs/jet/abs_part.svg /code/icons/complex-ln/outputs/magma/abs_part.svg /code/icons/complex-ln/outputs/plasma/abs_part.svg /code/icons/complex-ln/outputs/rainbow/abs_part.svg /code/icons/complex-ln/outputs/turbo/abs_part.svg

HSV | Viridis | Cividis | Inferno | Jet | Magma | Plasma | Rainbow | Turbo

Real

/code/icons/complex-exp/outputs/hsv/output_real.svg /code/icons/complex-exp/outputs/viridis/output_real.svg /code/icons/complex-exp/outputs/cividis/output_real.svg /code/icons/complex-exp/outputs/inferno/output_real.svg /code/icons/complex-exp/outputs/jet/output_real.svg /code/icons/complex-exp/outputs/magma/output_real.svg /code/icons/complex-exp/outputs/plasma/output_real.svg /code/icons/complex-exp/outputs/rainbow/output_real.svg /code/icons/complex-exp/outputs/turbo/output_real.svg

Imaginary

/code/icons/complex-exp/outputs/hsv/output_imag.svg /code/icons/complex-exp/outputs/viridis/output_imag.svg /code/icons/complex-exp/outputs/cividis/output_imag.svg /code/icons/complex-exp/outputs/inferno/output_imag.svg /code/icons/complex-exp/outputs/jet/output_imag.svg /code/icons/complex-exp/outputs/magma/output_imag.svg /code/icons/complex-exp/outputs/plasma/output_imag.svg /code/icons/complex-exp/outputs/rainbow/output_imag.svg /code/icons/complex-exp/outputs/turbo/output_imag.svg

Absolute

/code/icons/complex-exp/outputs/hsv/output_abs.svg /code/icons/complex-exp/outputs/viridis/output_abs.svg /code/icons/complex-exp/outputs/cividis/output_abs.svg /code/icons/complex-exp/outputs/inferno/output_abs.svg /code/icons/complex-exp/outputs/jet/output_abs.svg /code/icons/complex-exp/outputs/magma/output_abs.svg /code/icons/complex-exp/outputs/plasma/output_abs.svg /code/icons/complex-exp/outputs/rainbow/output_abs.svg /code/icons/complex-exp/outputs/turbo/output_abs.svg

Mathematics

Wolfram Alpha does a better job regarding this than I can. I do not understand the behaviour of these functions, especially at the branch points:

https://functions.wolfram.com/ElementaryFunctions/Log/visualizations/5/

https://functions.wolfram.com/ElementaryFunctions/Exp/visualizations/5/

Code

GPT o1 model produced these figures for me, here are the included code-blocks that have been version controlled as part of a larger icons repository.

#!/usr/bin/env python3
"""
Generate three separate SVG images:
1) Re[ln(x + i y)]
2) Im[ln(x + i y)]
3) |ln(x + i y)|

All plotted over x,y in [-4,4], with discrete color bands.

Usage:
  python plot_ln_complex.py [--cmap CMAP]

Example:
  python plot_ln_complex.py --cmap rainbow

This will produce:
  real_part.svg,
  imag_part.svg,
  abs_part.svg
"""

import numpy as np
import matplotlib.pyplot as plt
import argparse

def main():
    # A list of common matplotlib colormaps you might try for discrete color blocks
    all_cmaps = [
        'rainbow', 'hsv', 'jet', 'plasma', 'inferno', 'magma',
        'cividis', 'viridis', 'turbo'
    ]

    parser = argparse.ArgumentParser(
        description="Generate discrete color-band plots for Re, Im, and |ln(x + i y)| over [-4,4]x[-4,4]."
    )
    parser.add_argument(
        '--cmap',
        type=str,
        default='rainbow',
        help=(
            "Colormap to use. Some options include:\n"
            f"{', '.join(all_cmaps)}\n"
            "For more, see: https://matplotlib.org/stable/tutorials/colors/colormaps.html"
        )
    )
    args = parser.parse_args()

    # ---------------------------------------------------
    # Domain: x,y in [-4,4]
    # We'll include 401 points per axis so that 0 is included.
    # ---------------------------------------------------
    n_points = 401
    x_vals = np.linspace(-4, 4, n_points)
    y_vals = np.linspace(-4, 4, n_points)
    X, Y = np.meshgrid(x_vals, y_vals)

    # Avoid log(0) by masking out the point z=0
    Z = X + 1j * Y
    zero_mask = (X == 0) & (Y == 0)
    Z[zero_mask] = np.nan

    # Compute principal branch of the complex log
    with np.errstate(divide='ignore', invalid='ignore'):
        Z_ln = np.log(Z)

    # Extract real part, imaginary part, and magnitude
    ln_real = np.real(Z_ln)
    ln_imag = np.imag(Z_ln)
    ln_abs  = np.abs(Z_ln)

    # Decide how many discrete levels to use
    n_levels = 12  # Adjust if you want more or fewer color bands

    # ---------------------------------------------------
    # 1) Real part of ln(z)
    # ---------------------------------------------------
    fig_re, ax_re = plt.subplots(figsize=(6, 5), dpi=100)
    cs_re = ax_re.contourf(
        X, Y, ln_real,
        levels=n_levels,
        cmap=args.cmap
    )
    ax_re.set_aspect('equal', 'box')
    ax_re.axis('off')
    plt.subplots_adjust(left=0, right=1, top=1, bottom=0)
    fig_re.savefig("real_part.svg", format="svg", bbox_inches='tight', pad_inches=0)
    plt.close(fig_re)

    # ---------------------------------------------------
    # 2) Imag part of ln(z)
    # ---------------------------------------------------
    fig_im, ax_im = plt.subplots(figsize=(6, 5), dpi=100)
    cs_im = ax_im.contourf(
        X, Y, ln_imag,
        levels=n_levels,
        cmap=args.cmap
    )
    ax_im.set_aspect('equal', 'box')
    ax_im.axis('off')
    plt.subplots_adjust(left=0, right=1, top=1, bottom=0)
    fig_im.savefig("imag_part.svg", format="svg", bbox_inches='tight', pad_inches=0)
    plt.close(fig_im)

    # ---------------------------------------------------
    # 3) Absolute value of ln(z)
    # ---------------------------------------------------
    fig_abs, ax_abs = plt.subplots(figsize=(6, 5), dpi=100)
    cs_abs = ax_abs.contourf(
        X, Y, ln_abs,
        levels=n_levels,
        cmap=args.cmap
    )
    ax_abs.set_aspect('equal', 'box')
    ax_abs.axis('off')
    plt.subplots_adjust(left=0, right=1, top=1, bottom=0)
    fig_abs.savefig("abs_part.svg", format="svg", bbox_inches='tight', pad_inches=0)
    plt.close(fig_abs)


if __name__ == "__main__":
    main()
import numpy as np
import matplotlib
matplotlib.use('Agg')  # Use non-interactive backend
import matplotlib.pyplot as plt
import argparse
import os

def get_available_colormaps():
    """Returns a list of all available colormaps in matplotlib."""
    return plt.colormaps()

def exp_inv_complex(Z):
    """Compute exp(1/z) for a complex array Z."""
    with np.errstate(divide='ignore', invalid='ignore'):
        return np.exp(1 / Z)

def plot_complex_exp(cmap='RdYlBu_r', output_file=None, resolution=1001, singularity_size=0.01):
    """
    Plot the real component of exp(1/z) using the specified colormap.
    
    Args:
        cmap (str): Name of the matplotlib colormap to use.
                   Must be one of the available matplotlib colormaps.
        output_file (str, optional): Path to save the SVG file.
                                   If None, displays the plot instead.
        resolution (int): Number of points in each dimension. Higher values give better detail.
        singularity_size (float): Radius around z=0 to mask for the singularity.
    """
    # Generate grid points with high resolution
    x_vals = np.linspace(-1, 1, resolution)
    y_vals = np.linspace(-1, 1, resolution)
    X, Y = np.meshgrid(x_vals, y_vals)

    # Create complex grid Z = X + iY with smaller singularity
    Z = X + 1j * Y
    Z[np.abs(Z) < singularity_size] = np.nan

    # Compute exp(1/Z)
    W = exp_inv_complex(Z)
    real_part = np.real(W)
    real_part = np.clip(real_part, -2, 2)

    # Create minimal plot
    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111)
    im = ax.imshow(
        real_part,
        extent=[-1, 1, -1, 1],
        cmap=cmap,
        origin='lower',
        aspect='equal',
        interpolation='bilinear'
    )
    
    # Remove all decorations
    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_frame_on(False)
    
    plt.tight_layout()
    
    if output_file:
        # Ensure the output directory exists
        os.makedirs(os.path.dirname(output_file) if os.path.dirname(output_file) else '.', exist_ok=True)
        plt.savefig(output_file, format='svg', bbox_inches='tight', pad_inches=0)
        plt.close()
    else:
        plt.show()

def plot_imaginary_exp(cmap='RdYlBu_r', output_file=None, resolution=1001, singularity_size=0.01):
    """
    Plot the imaginary component of exp(1/z) using the specified colormap.
    
    Args:
        cmap (str): Name of the matplotlib colormap to use.
                   Must be one of the available matplotlib colormaps.
        output_file (str, optional): Path to save the SVG file.
                                   If None, displays the plot instead.
        resolution (int): Number of points in each dimension. Higher values give better detail.
        singularity_size (float): Radius around z=0 to mask for the singularity.
    """
    # Generate grid points with high resolution
    x_vals = np.linspace(-1, 1, resolution)
    y_vals = np.linspace(-1, 1, resolution)
    X, Y = np.meshgrid(x_vals, y_vals)

    # Create complex grid Z = X + iY with smaller singularity
    Z = X + 1j * Y
    Z[np.abs(Z) < singularity_size] = np.nan

    # Compute exp(1/Z)
    W = exp_inv_complex(Z)
    imag_part = np.imag(W)
    imag_part = np.clip(imag_part, -2, 2)

    # Create minimal plot
    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111)
    im = ax.imshow(
        imag_part,
        extent=[-1, 1, -1, 1],
        cmap=cmap,
        origin='lower',
        aspect='equal',
        interpolation='bilinear'
    )
    
    # Remove all decorations
    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_frame_on(False)
    
    plt.tight_layout()
    
    if output_file:
        # Ensure the output directory exists
        os.makedirs(os.path.dirname(output_file) if os.path.dirname(output_file) else '.', exist_ok=True)
        plt.savefig(output_file, format='svg', bbox_inches='tight', pad_inches=0)
        plt.close()
    else:
        plt.show()

def plot_absolute_exp(cmap='hsv', output_file=None, resolution=1001, singularity_size=0.01):
    """
    Plot the absolute value of exp(1/z) using the specified colormap.
    The color represents the argument (phase) of the complex number.
    
    Args:
        cmap (str): Name of the matplotlib colormap to use.
                   Must be one of the available matplotlib colormaps.
        output_file (str, optional): Path to save the SVG file.
                                   If None, displays the plot instead.
        resolution (int): Number of points in each dimension. Higher values give better detail.
        singularity_size (float): Radius around z=0 to mask for the singularity.
    """
    # Generate grid points with high resolution
    x_vals = np.linspace(-1, 1, resolution)
    y_vals = np.linspace(-1, 1, resolution)
    X, Y = np.meshgrid(x_vals, y_vals)

    # Create complex grid Z = X + iY with smaller singularity
    Z = X + 1j * Y
    Z[np.abs(Z) < singularity_size] = np.nan

    # Compute exp(1/Z)
    W = exp_inv_complex(Z)
    abs_val = np.abs(W)
    arg_val = np.angle(W, deg=True)
    
    # Normalize absolute value for better visualization
    abs_val = np.clip(abs_val, 0, 2)

    # Create minimal plot
    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111)
    
    # Plot the absolute value with phase coloring
    im = ax.imshow(
        abs_val,  # Use absolute value for the data
        extent=[-1, 1, -1, 1],
        cmap=cmap,
        origin='lower',
        aspect='equal',
        interpolation='bilinear'
    )
    
    # Remove all decorations
    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_frame_on(False)
    
    plt.tight_layout()
    
    if output_file:
        # Ensure the output directory exists
        os.makedirs(os.path.dirname(output_file) if os.path.dirname(output_file) else '.', exist_ok=True)
        plt.savefig(output_file, format='svg', bbox_inches='tight', pad_inches=0)
        plt.close()
    else:
        plt.show()

def main():
    """Main function to handle command line arguments and create the plots."""
    parser = argparse.ArgumentParser(
        description='Visualize various components of exp(1/z) with customizable colormap.',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter
    )
    
    parser.add_argument(
        '--cmap',
        type=str,
        default='RdYlBu_r',
        choices=get_available_colormaps(),
        help='Matplotlib colormap to use for visualization'
    )
    
    parser.add_argument(
        '--output-prefix',
        type=str,
        default=None,
        help='Prefix for output SVG files. If not provided, displays the plots instead.'
    )
    
    parser.add_argument(
        '--resolution',
        type=int,
        default=1001,
        help='Number of points in each dimension. Higher values give better detail.'
    )
    
    parser.add_argument(
        '--singularity-size',
        type=float,
        default=0.01,
        help='Radius around z=0 to mask for the singularity.'
    )
    
    args = parser.parse_args()
    
    # Generate all three visualizations
    if args.output_prefix:
        real_output = f"{args.output_prefix}_real.svg"
        imag_output = f"{args.output_prefix}_imag.svg"
        abs_output = f"{args.output_prefix}_abs.svg"
    else:
        real_output = None
        imag_output = None
        abs_output = None
    
    # Plot real part
    plot_complex_exp(args.cmap, real_output, args.resolution, args.singularity_size)
    
    # Plot imaginary part
    plot_imaginary_exp(args.cmap, imag_output, args.resolution, args.singularity_size)
    
    # Plot absolute value with the same colormap as the others
    plot_absolute_exp(args.cmap, abs_output, args.resolution, args.singularity_size)

if __name__ == '__main__':
    main()

Final Orbs

There has been a degree of iteration across functions and heatmaps, but ultimately here are the 5 plots that I have settled on for my 5 products; abaj.ai, bots.abaj.ai, games.abaj.ai, trades.abaj.ai, tools.abaj.ai.

/projects/mathematics/icons/
abs_hsv.svg
absolute hsv
/projects/mathematics/icons/
real_inferno.svg
real inferno
/projects/mathematics/icons/
imag_jet.svg
imaginary jet
/projects/mathematics/icons/
exp_abs_plasma.svg
absolute plasma
/projects/mathematics/icons/
exp_imag_plasma.svg
imaginary plasma