ComplexPhasePortrait.jl
Complex phase portraits for Julia.
Install / Use
/learn @JuliaHolomorphic/ComplexPhasePortrait.jlREADME
ComplexPhasePortrait.jl
This package is a Julia implementation of the phase portrait ideas presented in Elias Wegert's book "Visual Complex Functions".
Installation
From the Julia command prompt:
] add ComplexPhasePortrait
Examples
There is so far one exported function, portrait, and here I will try to detail its use. First we need function data over a grid.
using ComplexPhasePortrait
nx = 1000
x = range(-1, stop=1, length=nx)
Z = x' .+ reverse(x)*im
f = z -> (z - 0.5im)^2 * (z + 0.5+0.5im)/z
fz = f.(Z)
Now a basic phase plot.
img = portrait(fz)

Now for a basic plot using NIST coloring.
img = portrait(fz, ctype="nist")

Lines of constant phase are given by
img = portrait(fz, PTstepphase)

Lines of constant modulus are given by
img = portrait(fz, PTstepmod)

Finally, a conformal grid is given by
img = portrait(fz, PTcgrid)

You can also use custom colormaps to create unique visualizations. Below are examples using the viridis colormap and a custom colormap.
using ComplexPhasePortrait, ColorSchemes
viridis_colormap = [RGB(c.r, c.g, c.b) for c in ColorSchemes.viridis.colors]
img = portrait(fz, PTcgrid, colormap=viridis_colormap)

using ComplexPhasePortrait, Colors
custom_colormap = [RGB(1.0, 0.0, 0.0), RGB(0.0, 1.0, 0.0), RGB(0.0, 0.0, 1.0)]
img = portrait(fz, PTcgrid, colormap=custom_colormap)

Plot recipes
ComplexPhasePortrait.jl has support for plotting recipes for Plots.jl and Makie.jl.
Plots.jl:
using Plots
using LaTeXStrings
using ComplexPhasePortrait
using IntervalSets
f = z -> (z - 0.5im)^2 * (z + 0.5+0.5im)/z
phaseplot(-1..1, -1..1, f, PTcgrid, :ctype=>"nist";
xlabel=L"\Re\{z\}", ylabel=L"\Im\{z\}")

Makie.jl
Makie.jl is an optional dependency via package extensions, and the functionality to plot phase portraits becomes available if Makie.jl or one of its front-end packages is loaded before ComplexPhasePortrait.jl:
using GLMakie
using ComplexPhasePortrait
using IntervalSets
f = z -> (z - 0.5im)^2 * (z + 0.5+0.5im)/z
fig = Figure()
ax = Axis(fig[1, 1], aspect=1)
phase!(ax, -1..1, -1..1, f, portrait_type=PTcgrid, ctyle="nist")
display(fig)

Alternatively, one can use the function phase:
phase(x, y, f; kwargs...)
x and y can be vectors or ClosedIntervals; in the former case
f can be a matrix of appropriate size or a Function, in the latter
case, only a Function is possible.
Saving Images
To save the generated phase portraits as image file directly without use of Plots.jl or Makie.jl, you can use the save function from the Images.jl package. For example:
using Images
f = z -> (z - 0.5im)^2 * (z + 0.5+0.5im)/z
fz = f.(Z)
img = portrait(fz)
save("phase_portrait.png", img)
Related Skills
node-connect
342.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
84.7kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
342.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
84.7kCommit, push, and open a PR
