Skip to content

Catalog, presets and the gallery

catalog supplies functions; PlotPresets configures renders. The guide explains the distinction.

complexplorer.catalog module-attribute

catalog = _Catalog(_build_presets())

complexplorer.FunctionPreset dataclass

FunctionPreset(id: str, title: str, expression: str, func: ComplexFunction, domain_spec: DomainSpec = (lambda: DomainSpec())(), cmap_spec: CmapSpec = (lambda: CmapSpec(type='Phase', phase_sectors=6))(), scaling_spec: str | ScalingSpec = 'balanced', singularities: tuple[SingularityRecord, ...] = (), story: str = '', tags: tuple[str, ...] = (), pole_order: float | None = None, resolution: int | None = None, clip_ornament_to_domain: bool = True)

A curated complex function: renderable callable + serializable description.

answer_key_stats

answer_key_stats() -> dict

Derived geometry of the singularity answer key.

Returns count, count_by_type (sorted by type), and min_separation — the smallest Euclidean distance in the z-plane between any two singularity locations, or None when there are fewer than two. Computed from the hand-authored records only, never by analyzing func.

to_dict

to_dict() -> dict

JSON-ready record of everything EXCEPT the live func.

Floats are quantized to MANIFEST_SIGNIFICANT_DIGITS, so the record is identical on every platform. The live attributes keep full precision; only this record is quantized.

complexplorer.PlotPresets

Named plot-configuration presets (colormap + resolution bundles).

Each preset returns a plain dict of keyword arguments to spread into a plotting entry point, e.g. quick_plot(f, **PlotPresets.publication_ready()).

PlotPresets configures a render; catalog supplies a function. The registry complexplorer.catalog holds curated functions (expression, domain/colormap/scaling specs, singularity answer keys); these are the settings you draw one with.

publication_ready staticmethod

publication_ready() -> dict[str, Any]

Settings for publication-quality figures.

interactive staticmethod

interactive() -> dict[str, Any]

Settings for interactive exploration.

high_contrast staticmethod

high_contrast() -> dict[str, Any]

Settings for high contrast visualization.

complexplorer.quick_plot

quick_plot(func: ComplexFunction, domain: Domain | None = None, mode: str = '2d', **kwargs) -> Axes | pv.Plotter | None

Quick visualization of a complex function.

Parameters:

Name Type Description Default
func callable

Complex function to visualize

required
domain Domain

Domain to plot. Defaults to Rectangle(4, 4)

None
mode str

Plot mode: '2d', '3d', 'riemann'

'2d'
**kwargs

Additional arguments passed to plotting function

{}

Returns:

Type Description
Axes or Plotter object depending on mode
generate_gallery(out_dir: str | Path, *, selection: str | Iterable[str] | None = None, dpi: int = 150, resolution: int | None = None) -> dict

Render a selection of catalog presets into out_dir and return the manifest.

Parameters:

Name Type Description Default
out_dir path

Directory to write the bundle into (created if needed).

required
selection str | iterable of str | None

A tag, an iterable of preset ids, or None for the whole catalog.

None
resolution int

Samples per axis for the portraits. Defaults to one sample per output pixel.

None
dpi int

Portrait resolution.

150

Returns:

Type Description
dict

The index.json manifest that was written.

Polyhedral invariants

The Klein relative invariants, from which the polyhedral ornament family is built. A ratio of these carries the full rotation symmetry of a Platonic solid only at equal binary degree, where the automorphy factors cancel — a ratio of unequal degree renders and is not symmetric.

Transcribing these is the risk they exist to remove: the forms in the literature cohere as a set only for one orientation, and the commonly-remembered signs mix orientations, which silently destroys rotation invariance. Klein's syzygy is the check that catches it.

complexplorer.tetrahedral_vertex

tetrahedral_vertex(z)

Tetrahedral vertex form (classically Phi), binary degree 4.

Roots: the 4 vertices of a tetrahedron inscribed in the cube. Its coefficients are complex — this orientation of the tetrahedron is not symmetric about the real axis — which is expected rather than a transcription slip.

complexplorer.tetrahedral_dual_vertex

tetrahedral_dual_vertex(z)

The antipodal tetrahedron's vertex form (classically Psi), binary degree 4.

Roots: the other 4 cube vertices. tetrahedral_vertex * tetrahedral_dual_vertex == cube_vertex exactly: the two tetrahedra together are the cube.

complexplorer.octahedral_vertex

octahedral_vertex(z)

Octahedral vertex form (classically V), binary degree 6.

Only degree 5 as a polynomial: the sixth vertex sits at the north pole and so projects to infinity, contributing no finite root. Roots: the 6 octahedron vertices.

complexplorer.cube_vertex

cube_vertex(z)

Cube vertex form = octahedral face form (classically F), binary degree 8.

Roots: the 8 cube vertices, which are the face centres of the octahedron.

complexplorer.octahedral_edge

octahedral_edge(z)

Octahedral edge form (classically E), binary degree 12.

Roots: the 12 octahedron edge midpoints, which are the vertices of a cuboctahedron.

complexplorer.icosahedral_vertex

icosahedral_vertex(z)

Icosahedral vertex form (classically V), binary degree 12.

Only degree 11 as a polynomial: the twelfth vertex sits at the north pole and projects to infinity. Roots: the 12 icosahedron vertices.

Note the minus 11. The +11 variant is a different orientation of the icosahedron; paired with the Hessian and edge form below it fails Klein's syzygy by a factor of about 20 and destroys the rotation invariance of every ratio built from it.

complexplorer.icosahedral_hessian

icosahedral_hessian(z)

Icosahedral Hessian (classically H), binary degree 20.

Roots: the 20 dodecahedron vertices, which are the face centres of the icosahedron.

complexplorer.icosahedral_edge

icosahedral_edge(z)

Icosahedral edge form (classically T), binary degree 30.

Roots: the 30 icosahedron edge midpoints, which are the vertices of an icosidodecahedron.

Note the signs on the 522 terms run minus then plus, the reverse of the variant usually quoted.

complexplorer.polyhedral_features

polyhedral_features(solid: str, kind: str = 'vertices') -> np.ndarray

The finite projected locations of one class of a solid's features.

Builds the solid explicitly and stereographically projects the requested features onto the complex plane, using the library's canonical convention -- the south pole maps to 0 and the north pole to infinity, matching :func:~complexplorer.core.field.sample_sphere. These are the roots of the corresponding form above, and the source those forms' coefficients were derived from.

Constructed rather than solved, deliberately. Solving a degree-30 polynomial numerically gives roots that agree to perhaps ten significant digits between linear-algebra implementations, which is not enough for a preset record that is serialized into a byte-compared manifest. Projected geometry depends only on sqrt and trigonometry, which agree to within one unit in the last place everywhere.

Parameters:

Name Type Description Default
solid ('tetrahedron', 'tetrahedron_dual', 'octahedron', 'icosahedron')

Which solid. The cube and the dodecahedron are the faces of the octahedron and the icosahedron respectively.

'tetrahedron'
kind ('vertices', 'faces', 'edges')

Which class of feature: vertices, face centres, or edge midpoints, each projected onto the unit sphere first.

'vertices'

Returns:

Type Description
ndarray

Complex locations, in a canonical order (by modulus, then by argument) so the result is reproducible. A feature at the north pole is omitted, because it projects to infinity and has no finite location: that happens for the vertices of the octahedron and the icosahedron, each of which has one there. Every other combination returns the full set.

Raises:

Type Description
ValidationError

If solid or kind is not recognized.

Examples:

>>> import numpy as np
>>> dodecahedron = polyhedral_features("icosahedron", "faces")
>>> len(dodecahedron)
20
>>> bool(np.abs(icosahedral_hessian(dodecahedron)).max() < 1e-9)
True