API Reference

Eunoia.EunoiaModule
Eunoia

Julia bindings for eunoia, a Rust library for area-proportional Euler and Venn diagrams.

The native code is the eunoia-capi cdylib, which speaks a small JSON-in/ JSON-out C ABI (eunoia_euler, eunoia_venn, eunoia_version, eunoia_free). This module dlopen's it and exposes euler, venn, and version.

Locating the library

At load time the shared library is resolved in this order:

  1. ENV["EUNOIA_CAPI_LIB"] — an explicit path to a locally built libeunoia_capi. Set this during development: cargo build -p eunoia-capi --release then point at target/release/libeunoia_capi.{so,dylib}.
  2. The bundled eunoia artifact declared in Artifacts.toml (downloaded lazily on first use; populated by gen/generate_artifacts.jl from a GitHub release).

If neither is available a descriptive error is raised.

source
Eunoia.ContainerType

The fitted universe box drawn around a diagram fit with a complement. The container's area minus the union of the shapes matches the requested complement area.

source
Eunoia.EulerFitType
EulerFit{S}

Result of fitting an area-proportional Euler diagram with shapes of type S.

Fields:

  • shapes: fitted shapes, one per input set, in input order.
  • original_values: the requested exclusive area per region (keyed by combination string, e.g. "A&B").
  • fitted_values: the fitted exclusive area per region.
  • residuals: original_values − fitted_values per region.
  • region_error: per-region error (always in exclusive form).
  • diag_error: eulerAPE-style worst-case region error.
  • stress: venneuler-style stress metric.
  • loss: final value of the optimizer's objective.
  • iterations: optimizer iteration count.
  • container: the fitted universe box when fit with a complement, else nothing.

The plot_data field holds the native renderable geometry (region polygons and label anchors); it backs plotting and is not part of the stable public API.

source
Eunoia.LabelPlacementType
LabelPlacement

A resolved label position returned by place_labels. anchor is the centre of the label box. kind is one of :interior, :exterior_raycast, :exterior_force_directed, or :exterior_elbow (:unknown for a future native variant). For exterior placements that need a leader line, tether is the inside-region point the leader starts from, leader_end is where it meets the label box, and leader_waypoints are the intermediate polyline vertices (empty for straight leaders, populated for elbow leaders); all three are nothing/ empty for interior placements.

source
Eunoia.VennFitType
VennFit{S}

Result of laying out a (non-proportional) Venn diagram. Shares EulerFit's structure, but the layout is topological: every set intersection is drawn regardless of area, so the proportional-error metrics are not meaningful (left at zero) and original_values is empty. fitted_values holds the geometric area of each region.

source
Eunoia.eulerMethod
euler(values; shape="circle", input_type="exclusive",
      complement=nothing, seed=nothing, loss=nothing, …)

Fit an area-proportional Euler diagram. values is one of:

  • a mapping from combination strings to areas, where a key is a single set ("A") or an &-joined intersection ("A&B"):

    euler(Dict("A" => 5, "B" => 3, "A&B" => 1.5))
  • a mapping from set names to membership collections (vector/set/tuple); each element is counted into the canonical region of the sets it belongs to, yielding exclusive per-region counts (so input_type must stay "exclusive"):

    euler(Dict("A" => ["x", "y"], "B" => ["y", "z"]))

Keyword arguments:

  • shape: "circle" (default), "ellipse", "square", or "rectangle".
  • input_type: "exclusive" (default; per-region areas) or "inclusive" (set sizes that include overlaps; the core converts internally and the reported fitted_values/residuals are reconstructed in the inclusive scale).
  • complement: target "universe" area outside every set (opts into container fitting); nothing to disable.
  • seed: RNG seed for reproducible restarts; nothing for default.
  • max_sets: raise the set-count ceiling above the core default (32); clamped core-side to the hard cap (63). nothing keeps the default. Note that a fully-overlapping n-set diagram has 2^n - 1 regions, so large dense inputs remain intractable regardless.

Fitting knobs (all optional; nothing keeps the core default). Invalid string tokens are rejected by the native core and surface as an error:

  • loss: objective function. One of "sum_squared" (default), "sum_absolute", "sum_absolute_region_error", "sum_squared_region_error", "max_absolute", "max_squared", "root_mean_squared", "stress", "diag_error", "log_sum_absolute", or a C¹-smooth surrogate "smooth_sum_absolute", "smooth_sum_absolute_region_error", "smooth_max_absolute", "smooth_max_squared", "smooth_diag_error", "smooth_log_sum_absolute".
  • loss_eps: smoothing parameter for the six smooth_* losses (default 1e-3); ignored by the non-smooth losses.
  • n_restarts: number of randomly seeded restarts (default 10).
  • optimizer: final-layout solver. One of "levenberg_marquardt", "lbfgs", "nelder_mead", "trf", "cmaes_lm", or "cmaes_trf" (default).
  • mds_solver: initial-layout (MDS) solver, "levenberg_marquardt" (default) or "lbfgs".
  • initial_sampler: restart-position sampler, "uniform" (default) or "latin_hypercube".
  • cmaes_fallback_threshold: loss above which the cmaes_* optimizers fire their global escape stage (default 1e-3).
  • max_iterations: per-optimizer iteration cap (default 200).
  • tolerance: unified convergence tolerance (default 1e-3).
  • xtol, ftol, gtol: fine-grained Levenberg-Marquardt tolerances overriding the defaults derived from tolerance.
  • jobs: thread count for the restart loop; a pure wall-time knob, the chosen layout is identical regardless of value.

Plot-tuning knobs (all optional; nothing keeps the core default). These shape the plot_data geometry used for rendering, not the fit:

  • n_vertices: vertices per polygonized shape/region outline (default 200). Lower values give coarser outlines; higher values, smoother ones.
  • label_precision: pole-of-inaccessibility search precision for label anchors, in coordinate units (default 0.01).
  • sliver_threshold: minimum region-piece area, as a fraction of the largest piece, below which a piece is rejected as a polygonization artifact (default 1e-3); 0.0 disables the filter.

Returns an EulerFit carrying the fitted shapes, the original_values/fitted_values/residuals per region, the per-region region_error, the scalar fit metrics, and—if a complement was given—a container.

source
Eunoia.eunoiaplotFunction
eunoiaplot(fit; colors, fills, edges, labels, quantities, legend, complement,
           fontsize=14, label_placement=true, leader_style=(;), figure=(;), axis=(;))

Render a fitted EulerFit/VennFit as a publication-ready Makie figure (equal aspect, no axis decorations), returning a Makie.FigureAxisPlot.

This requires a Makie backend to be loaded — the implementation lives in a package extension that activates on using CairoMakie (or GLMakie/WGLMakie). The bare Makie plot(fit)/plot!(ax, fit) recipe forms also work once a backend is loaded.

Styling keywords mirror the eunoia-py plot() API:

  • colors: per-set colors — a vector (shape order) or a Dict(name => color); omitted uses a built-in categorical palette. Region fills blend the member colors perceptually (OKLab).
  • fills: Dict(combo => style) per-region fill overrides.
  • edges: set-outline style — a uniform style, a per-set Dict, or a vector.
  • labels: false/true/nothing, a per-set Dict, or a uniform style.
  • quantities: false/true, "original"/"fitted", "counts"/"percent", or a Dict.
  • legend: false/true or a Dict of Legend keywords.
  • complement: container-box style Dict (drawn only when the fit has one).
  • fontsize: base label font size in points (quantities render smaller).

Collision-aware labels:

  • label_placement: true (default) places labels collision-aware via place_labels: each region's label is measured (Makie text metrics), positioned inside its region when it fits, else pushed outside with a leader line. Set names and quantities are combined into one box per region, so a set name and its region quantity never overlap. The default uses the "raycast" exterior solver with straight leaders; pass a NamedTuple/Dict of place_labels strategy knobs (placement, leader, tether, margin, iterations, precision, leader_gap, min_gap) to change it, e.g. label_placement = (; placement = "force_directed") or label_placement = (; leader = "elbow", tether = "boundary"). Pass label_placement=false to instead draw labels at their raw anchors.
  • leader_style: collection of lines! keywords styling the leader lines.

Collision-aware placement needs the axis (to convert pixel text metrics to layout units), so it is available through eunoiaplot/eunoiaplot! only; the bare plot(fit) recipe form ignores label_placement.

source
Eunoia.eunoiaplot!Function
eunoiaplot!(ax, fit; label_placement=true, leader_style=(;), kwargs...)

Draw a fitted diagram into an existing Makie axis ax. Same styling keywords as eunoiaplot (including label_placement/leader_style for collision-aware labels, on by default); does not alter the axis aspect or decorations.

source
Eunoia.place_labelsMethod
place_labels(fit, sizes; placement=nothing, leader=nothing, margin=nothing,
             iterations=nothing, precision=nothing, tether=nothing,
             leader_gap=nothing, min_gap=nothing)

Resolve collision-aware label positions for the regions of a fitted EulerFit/VennFit, given the rendered label box sizes.

The core can't place labels without their on-screen sizes (font metrics it never sees at fit time), so this is a separate call from euler: measure each label, then ask for placements. sizes is a mapping from region/combination strings ("A", "A&B", …) to a (width, height) tuple in the same coordinate units as the fitted shapes. Only regions present in both sizes and the fit's geometry get a placement; degenerate inputs are silently skipped.

Each placement tries to sit inside its region; one that can't fit is pushed outside with a leader line. Returns a Dict{String,LabelPlacement} (see LabelPlacement).

Strategy knobs (all optional; nothing keeps the core default). Invalid string tokens are rejected by the native core and surface as an error:

  • leader: leader edge type, "straight" (default) or "elbow" (d3-pie style orthogonal leaders with column-based placement).
  • placement: exterior solver for straight leaders, "raycast" (default) or "force_directed" (spring/repulsion relaxation for crowded diagrams); ignored for "elbow".
  • margin: gap between the diagram and exterior labels (both edge types); the per-region proportional default applies when omitted.
  • iterations: iteration cap for "force_directed" (default 200); ignored otherwise.
  • precision: pole-of-inaccessibility search precision (default 0.01).
  • tether: where an exterior leader attaches to its region, "poi" (default, the pole of inaccessibility) or "boundary" (the region's outer ring).
  • leader_gap: visible gap between the leader tip and the label box (default 0.0).
  • min_gap: minimum vertical spacing between stacked "elbow" labels; ignored otherwise.
fit = euler(Dict("A" => 5, "B" => 3, "A&B" => 1.5))
placements = place_labels(fit, Dict("A" => (0.6, 0.3), "B" => (0.6, 0.3));
                          placement="force_directed")
source
Eunoia.vennMethod
venn(sets; shape="circle")

Build a canonical Venn diagram. sets selects the set names, as one of:

  • an Integer nn sets with default names "A", "B", …;
  • a vector of set names, e.g. ["cat", "dog", "fish"];
  • a mapping whose keys are set/combination labels (the distinct base set names are extracted; values are ignored, since a Venn layout is non-proportional).

The number of names selects the arrangement; shape is "circle" (n ≤ 3), "ellipse" (n ≤ 5), "square", or "rectangle" (n ≤ 3).

venn(["A", "B", "C"]; shape="ellipse")
venn(3)

Returns a VennFit: the same structure as EulerFit, but the layout is topological, so fitted_values holds each region's geometric area and original_values is empty.

source
Eunoia.versionMethod
version() -> String

Return the version of the underlying eunoia-capi native library.

source