API Reference

Complete reference for all exported functions and types.

Main Functions

ChordPlots.cooccurrence_matrixFunction
cooccurrence_matrix(df::DataFrame, columns::Vector{Symbol}; normalize=false)

Compute a co-occurrence matrix from a DataFrame.

Each row in the DataFrame represents one observation. Labels from different columns that appear in the same row are considered co-occurring.

Arguments

  • df::DataFrame: Input data
  • columns::Vector{Symbol}: Column names to analyze

Keywords

  • normalize::Bool=false: If true, normalize counts so matrix sums to 1 (frequencies)

Returns

  • CoOccurrenceMatrix: Matrix of co-occurrence counts or frequencies

Note on normalized / combined data

The matrix can hold raw counts or proportions. To combine multiple donors/samples, normalize each by its own total sum then take the element-wise mean — use mean_normalized. Layout uses only relative magnitudes; set min_ribbon_value and min_arc_flow to match your scale (e.g. small for proportions).

Example

df = DataFrame(
    V_call = ["IGHV1-2*01", "IGHV1-2*01", "IGHV3-23*01"],
    D_call = ["IGHD2-2*01", "IGHD3-10*01", "IGHD2-2*01"],
    J_call = ["IGHJ6*01", "IGHJ6*01", "IGHJ4*02"]
)
cooc = cooccurrence_matrix(df, [:V_call, :D_call, :J_call])
source
ChordPlots.chordplotFunction
chordplot(cooc::AbstractChordData)
chordplot!(ax, cooc::AbstractChordData)

Create a chord diagram from co-occurrence data.

Attributes (grouped by purpose)

Radii and arc size

  • inner_radius = 0.92: Inner radius for ribbons
  • outer_radius = 1.0: Outer radius for arcs
  • arc_width = 0.08: Width of arc segments

Arc and gap layout

  • gap_fraction = 0.03: Fraction of circle reserved for gaps
  • arc_scale = 1.0: Scale for arc portion; < 1 adds extra gaps
  • sort_by = :group: Order arcs by :group, :value, or :none
  • label_order = nothing: Fixed order (overrides sort_by)

Ribbon appearance

  • ribbon_width_power = 1.0: Exponent for ribbon width
  • min_ribbon_value = 0: Hide ribbons below this value
  • ribbon_tension = 0.5: Bezier curve tension

Arc appearance

  • arc_strokewidth = 0.5: Border width
  • arc_strokecolor = :black: Border color

Labels

  • show_labels = true: Whether to show labels
  • label_offset = 0.12: Distance from arc to label
  • label_fontsize = 10: Font size
  • label_color = :black: Color (use :group for category colors)
  • rotate_labels = true: Rotate labels to follow arcs
  • label_justify = :inside: :inside or :outside
  • min_arc_flow = 0: Hide arcs below this flow

Colors

  • colorscheme = :group: Color scheme (:group, :categorical, or AbstractColorScheme)

Opacity (unified)

  • alpha = 1.0: Base opacity per component (ribbons, arcs, labels). Accepts Real, Tuple, or ComponentAlpha. Scaling off = fixed opacity; scaling on = upper bound (min_alpha to this).
  • alpha_by_value = false: Value-based scaling. Accepts Bool or ValueScaling. This is the only toggle for “scale by value” vs “fully opaque”:
    • For each component (ribbons, arcs, labels), on → opacity scales by value from min_alpha to the component’s base alpha; off → opacity is that component base alpha (fixed).
    • false or unknown → no scaling (all components 1.0). true → all components scaled. ValueScaling(; components=(ribbons=..., arcs=..., labels=...)) → per-component.

Focus (highlight subset)

  • focus_group = nothing: Group to apply focus styling
  • focus_labels = nothing: Labels to keep highlighted
  • dim_color = RGB(0.55, 0.55, 0.55): Color for dimmed elements
  • dim_alpha = 0.25: Alpha for dimmed elements

Example

using CairoMakie, ChordPlots, DataFrames

df = DataFrame(
    V_call = ["V1", "V1", "V2", "V2", "V3"],
    D_call = ["D1", "D2", "D1", "D2", "D1"],
    J_call = ["J1", "J1", "J2", "J2", "J1"]
)
cooc = cooccurrence_matrix(df, [:V_call, :D_call, :J_call])

# Basic plot
fig, ax, plt = chordplot(cooc)

# Per-component opacity
chordplot(cooc; alpha=ComponentAlpha(ribbons=0.5, arcs=1.0, labels=1.0))

# Value-based scaling (ribbons and arcs only; labels at 1.0)
chordplot(cooc; alpha_by_value=ValueScaling(
    enabled=true,
    components=(ribbons=true, arcs=true, labels=false)
))
source
chordplot(df::DataFrame, columns; kwargs...)

Create chord plot directly from DataFrame.

source
ChordPlots.setup_chord_axis!Function
setup_chord_axis!(ax::Axis; outer_radius=1.0, label_offset=0.12, padding=0.2)

Configure axis for chord plot display (equal aspect, no decorations). Sets axis limits so that the circle and labels fit: limits extend to outer_radius + label_offset + padding. Use the same outer_radius and label_offset as in your chordplot! call so that large label offsets don't get clipped and the title doesn't overlap the labels.

source
ChordPlots.compute_layoutFunction
compute_layout(cooc::AbstractChordData, config::LayoutConfig=LayoutConfig())

Compute the complete layout for a chord diagram.

Algorithm

  1. Calculate total flow for each label
  2. Allocate angular width proportional to flow
  3. Assign arc positions
  4. Generate ribbon endpoints based on co-occurrence values
source

Data Types

ChordPlots.CoOccurrenceMatrixType
CoOccurrenceMatrix{T<:Real, S<:AbstractString}

Stores co-occurrence counts between labels with group information.

Type Parameters

  • T: Numeric type for counts (enables Integer or Float)
  • S: String type for labels

Fields

  • matrix::Matrix{T}: Symmetric co-occurrence matrix (counts, frequencies, or e.g. mean normalized counts)
  • labels::Vector{S}: Combined list of all labels
  • groups::Vector{GroupInfo{S}}: Group information
  • label_to_index::Dict{S, Int}: Fast label lookup

Example

cooc = CoOccurrenceMatrix(df, [:V_call, :D_call, :J_call])
cooc["IGHV1-2*01", "IGHD2-2*01"]  # Get co-occurrence count
source
ChordPlots.NormalizedCoOccurrenceMatrixType
NormalizedCoOccurrenceMatrix{T<:Real, S<:AbstractString} <: AbstractChordData

Co-occurrence data in frequency form (matrix typically sums to 1) or combined from multiple sources (e.g. mean of per-sample normalized matrices).

Same structure as CoOccurrenceMatrix; the type signals that values are on a 0–1 scale so e.g. min_ribbon_value / min_arc_flow can use small thresholds. Layout and plotting use the same logic (scale-invariant).

source

Data Management

ChordPlots.filter_top_nFunction
filter_top_n(cooc::AbstractChordData, n::Int)

Keep only the top n labels by total flow. Returns the same type as cooc.

source
ChordPlots.filter_by_thresholdFunction
filter_by_threshold(cooc::AbstractChordData, min_value)

Create a new matrix with values below threshold set to zero. Returns the same type as cooc.

source
ChordPlots.normalizeFunction
normalize(cooc::CoOccurrenceMatrix) -> NormalizedCoOccurrenceMatrix

Return a normalized version where all values sum to 1. Use for comparing matrices from different sample sizes or before combining multiple sources.

source
normalize(cooc::NormalizedCoOccurrenceMatrix)

Return copy unchanged (already normalized).

source
ChordPlots.mean_normalizedFunction
mean_normalized(coocs::AbstractVector{<:AbstractChordData}) -> NormalizedCoOccurrenceMatrix

Combine multiple co-occurrence matrices by normalizing each by its own total sum and taking the element-wise mean. Result sums to 1. Matrices may have different labels; they are aligned to the union of all labels (per group), missing entries as zero.

source
ChordPlots.expand_labelsFunction
expand_labels(coocs::AbstractVector{<:AbstractChordData}) -> Vector{AbstractChordData}

Expand all matrices to a common label set (union of all labels per group). Labels not present in a matrix get zero flow/connections. Use this when you want to plot multiple matrices with the same labels appearing in the same positions, even if some matrices are missing certain labels.

Returns matrices of the same type as input (CoOccurrenceMatrix or NormalizedCoOccurrenceMatrix).

Example

# Two matrices with different genes
cooc_A = cooccurrence_matrix(df_A, [:V_call, :J_call])
cooc_B = cooccurrence_matrix(df_B, [:V_call, :J_call])

# Expand to union of labels (missing labels get zero flow → empty arcs)
expanded_A, expanded_B = expand_labels([cooc_A, cooc_B])

# Now both have the same labels; plot with consistent positions
order = label_order(expanded_A)  # or label_order(expanded_B) — same labels
chordplot!(ax1, expanded_A; label_order = order)
chordplot!(ax2, expanded_B; label_order = order)
source

Comparison

Base.diffFunction
diff(a::AbstractChordData, b::AbstractChordData; absolute=false) -> NormalizedCoOccurrenceMatrix

Compute the difference between two co-occurrence matrices: a - b. Both matrices are first normalized (so differences are in frequency space), then aligned to a common label set. Use this to visualize what changed between two conditions.

Keywords

  • absolute::Bool = false: If true, return absolute differences |a - b| (all positive, thickest ribbons = biggest changes). If false (default), return signed differences (positive where a > b, negative where a < b) — use with diverging_colors or diff_colors to show increases (red) vs decreases (blue).

Returns

A NormalizedCoOccurrenceMatrix with the differences. Note: the result does not sum to 1 (it's a difference map, not a probability distribution).

Example

# Gene knockout experiment: what connections changed?
cooc_wt = cooccurrence_matrix(df_wildtype, [:V_call, :J_call])
cooc_ko = cooccurrence_matrix(df_knockout, [:V_call, :J_call])

# Signed differences with diverging colormap (blue = decrease, red = increase)
d = diff(cooc_ko, cooc_wt)  # ko - wt: positive means KO has more
chordplot(d; colorscheme=diff_colors(d))

# Or absolute differences (just magnitude of change)
d_abs = diff(cooc_ko, cooc_wt; absolute=true)
chordplot(d_abs; colorscheme=:Reds)

See also: normalize, expand_labels, diverging_colors, diff_colors

source

Data Exploration

Inspect the distribution of co-occurrence values to choose thresholds (e.g. min_ribbon_value, filter_by_threshold):

ChordPlots.cooccurrence_valuesFunction
cooccurrence_values(cooc::AbstractChordData) -> Vector{Float64}

Return the upper-triangle co-occurrence values (each pair counted once). Use with histogram(cooccurrence_values(cooc)) to inspect the distribution and choose min_ribbon_value.

source
cooccurrence_values(coocs::AbstractVector{<:AbstractChordData}) -> Vector{Float64}

Concatenate co-occurrence values from all matrices. Use to plot the combined distribution when choosing a threshold across multiple donors/samples.

source
ChordPlots.value_histogramFunction
value_histogram(data; kwargs...)

Create a figure with a histogram of co-occurrence values. data can be a single AbstractChordData or an abstract container of them. Returns (fig, ax, hist). Use to choose min_ribbon_value from the distribution.

source
ChordPlots.value_histogram!Function
value_histogram!(ax, data; kwargs...)

Plot histogram of co-occurrence values on the given axis. data can be a single AbstractChordData or an abstract container of them (e.g. Vector of matrices). Use to inspect the distribution and choose a threshold (e.g. min_ribbon_value). Keyword arguments are passed to histogram!.

source

Layout Functions

ChordPlots.label_orderFunction
label_order(cooc::AbstractChordData; sort_by=:group, label_order=nothing)

Return the label names in the order they appear around the circle for the given co-occurrence matrix and layout options. Use this to reuse the same order when creating a second chord plot for comparison.

Arguments

  • cooc: Co-occurrence matrix (from the plot whose order you want to copy).
  • sort_by: Same as in chordplot (:group, :value, or :none). Must match the plot you are copying from.
  • label_order: If the first plot used a custom order, pass the same here (vector of indices or label names).

Returns

  • Vector of label names in circle order (same element type as cooc.labels).

Example

# First plot (default sort_by=:group)
fig1, ax1, plt1 = chordplot(cooc_A)
setup_chord_axis!(ax1)

# Get order from cooc_A and apply to cooc_B for comparable layout
order = label_order(cooc_A)
fig2, ax2, plt2 = chordplot(cooc_B; label_order = order)
setup_chord_axis!(ax2)
source
label_order(coocs::AbstractVector{<:AbstractChordData}; sort_by=:group, include_all=true)

Compute a unified label order from multiple co-occurrence matrices with potentially different label sets. Returns a Vector{String} of labels suitable for chordplot(...; label_order=...) to ensure consistent label positioning across plots.

Arguments

  • coocs: Vector of co-occurrence matrices (may have different labels).

Keywords

  • sort_by::Symbol = :group: Sorting method (:group keeps groups together sorted by flow, :value sorts all by flow, :none uses union order).
  • include_all::Bool = true: If true, include all labels from the union (labels missing in some matrices contribute zero flow). If false, include only labels present in all matrices.

Returns

  • Vector{String} of label names in order.

Example

# Two matrices with overlapping but different genes
cooc_A = cooccurrence_matrix(df_A, [:V_call, :J_call])
cooc_B = cooccurrence_matrix(df_B, [:V_call, :J_call])

# Get a combined order that works for both
order = label_order([cooc_A, cooc_B])

# Plot with same label positions
chordplot!(ax1, cooc_A; label_order = order)
chordplot!(ax2, cooc_B; label_order = order)
source
ChordPlots.LayoutConfigType
LayoutConfig{T<:Real}

Configuration for layout computation. Parameters are grouped below; they work together and are non-conflicting.

Fields (grouped)

Radii

  • inner_radius::T: Inner radius for ribbon attachment
  • outer_radius::T: Outer radius for arcs

Arc and gap layout (angle allocation)

  • gap_fraction::T: Fraction of the full circle (2π) reserved for gaps between arcs (baseline)
  • arc_scale::T: Scale for the arc (content) portion only. Content = (1 - gapfraction)*arcscale of 2π; rest is gap. Use < 1 for extra separation.

Orientation

  • start_angle::T: Starting angle (0 = right, π/2 = top)
  • direction::Int: 1 = counterclockwise, -1 = clockwise

Order

  • sort_by::Symbol: How to order arcs (:group, :value, :none). Ignored when label_order is set.
  • label_order::Union{Nothing, Vector{Int}}: If set, fixed order of label indices on the circle (overrides sort_by)

Ribbon thickness

  • ribbon_width_power::T: Exponent for ribbon width (value/flow)^power; > 1 makes thick vs thin more dramatic
source
ChordPlots.ChordLayoutType
ChordLayout{T<:Real}

Complete layout information for rendering a chord diagram.

Fields

  • arcs::Vector{ArcSegment{T}}: Arc segments for each label
  • ribbons::Vector{Ribbon{T}}: All ribbons
  • inner_radius::T: Inner radius for ribbons
  • outer_radius::T: Outer radius for arcs
  • gap_angle::T: Gap between adjacent arcs
source

Opacity Configuration

ChordPlots.ComponentAlphaType
ComponentAlpha

Named opacity settings for chord diagram components. All values are clamped to [0, 1].

Fields

  • ribbons::Float64: Opacity for ribbons (connections)
  • arcs::Float64: Opacity for arcs (outer segments)
  • labels::Float64: Opacity for labels

Constructors

  • ComponentAlpha(ribbons, arcs, labels): Set each component separately
  • ComponentAlpha(v): Set all components to the same value
  • ComponentAlpha((r, a, l)): Construct from a tuple

Example

# All components at 70% opacity
chordplot(cooc; alpha=ComponentAlpha(0.7))

# Semi-transparent ribbons, solid arcs and labels
chordplot(cooc; alpha=ComponentAlpha(0.5, 1.0, 1.0))

# Using named arguments for clarity
chordplot(cooc; alpha=ComponentAlpha(ribbons=0.5, arcs=1.0, labels=1.0))
source
ChordPlots.ValueScalingType
ValueScaling

Value-based opacity scaling. Each of ribbons, arcs, and labels is a toggle:

  • On (true): opacity is scaled by value from min_alpha (weakest) to the component's base alpha from alpha (strongest).
  • Off (false): opacity is the component's base alpha from alpha (fixed; no scaling). Use alpha=ComponentAlpha(ribbons=0.6, arcs=0.8, labels=1) for fixed per-component opacity when not scaling.

Fields

  • enabled::Bool: Master switch; when false, no component is scaled.
  • ribbons::Bool: Toggle ribbon opacity by co-occurrence value.
  • arcs::Bool: Toggle arc opacity by total flow.
  • labels::Bool: Toggle label opacity by total flow.
  • min_alpha::Float64: Minimum opacity when scaling (used only for components that are on).
  • scale::Symbol: :linear or :log scaling.

Components argument

components can be given as:

  • Named tuple (recommended): (ribbons=true, arcs=true, labels=false) — order and meaning are clear.
  • Positional tuple: (ribbons, arcs, labels) i.e. (true, true, false) in that order.

Examples

# Scale all three by value
chordplot(cooc; alpha_by_value=ValueScaling(enabled=true))

# Scale ribbons and arcs only; labels fully opaque
chordplot(cooc; alpha_by_value=ValueScaling(
    enabled=true,
    components=(ribbons=true, arcs=true, labels=false),
    min_alpha=0.2
))

# Only ribbons scaled; arcs and labels at 1.0
chordplot(cooc; alpha_by_value=ValueScaling(enabled=true, components=(ribbons=true, arcs=false, labels=false)))
source

Color Functions

ChordPlots.group_colorsFunction
group_colors(cooc::AbstractChordData; palette=:default)

Create a color scheme based on groups using Makie's default categorical palette (same as AlgebraOfGraphics uses - Wong colors, colorblind-friendly).

Arguments

  • palette::Symbol: Color palette style (:default for Makie/AoG palette, :modern for custom)
source
ChordPlots.diverging_colorsFunction
diverging_colors(cooc::AbstractChordData; negative=:steelblue, neutral=:white, positive=:firebrick, symmetric=true)

Create a diverging color scheme for signed values (e.g., from diff()).

Both ribbons and arcs are colored by their signed values:

  • Ribbons: colored by the connection's difference value
  • Arcs: colored by net flow (sum of all differences for that label), showing overall enrichment (positive → red) vs depletion (negative → blue)

Use with diff(a, b; absolute=false) to visualize increases vs decreases.

Arguments

  • cooc: The chord data (used to determine value range)
  • negative: Color for negative values/depletion (default: steel blue)
  • neutral: Color for zero (default: near-white)
  • positive: Color for positive values/enrichment (default: firebrick red)
  • symmetric: If true (default), range is symmetric around zero

Example

d = diff(cooc_after, cooc_before; absolute=false)  # positive = increase
fig, ax, plt = chordplot(d; colorscheme=diverging_colors(d))
# Blue arcs = labels with overall decreased connections
# Red arcs = labels with overall increased connections
source
ChordPlots.diff_colorsFunction
diff_colors(cooc::AbstractChordData; kwargs...)

Alias for diverging_colors - creates a color scheme for difference matrices.

Example

d = diff(cooc_after, cooc_before; absolute=false)
chordplot(d; colorscheme=diff_colors(d))
source
ChordPlots.GroupColorSchemeType
GroupColorScheme{C<:Colorant}

Assigns colors based on label groups.

Fields

  • group_colors::Dict{Symbol, C}: Color for each group
  • default_color::C: Fallback color
source
ChordPlots.GradientColorSchemeType
GradientColorScheme

Colors based on a gradient (e.g., by value).

Fields

  • colormap::Symbol: Makie colormap name
  • range::Tuple{Float64, Float64}: Value range for mapping
source
ChordPlots.DivergingColorSchemeType
DivergingColorScheme{C<:Colorant}

Color scheme for signed values (e.g., differences) using a diverging colormap. Maps negative values to one color, zero to neutral, positive to another color.

Both ribbons and arcs are colored by their signed values:

  • Ribbons: colored by the connection's difference value
  • Arcs: colored by net flow (sum of all differences for that label), showing overall enrichment (positive/red) vs depletion (negative/blue)

Fields

  • negative_color::C: Color for negative values (depletion)
  • neutral_color::C: Color for zero/neutral values
  • positive_color::C: Color for positive values (enrichment)
  • range::Tuple{Float64, Float64}: (min, max) value range for normalization
  • symmetric::Bool: If true, range is symmetric around zero (max absolute value)
source

categorical_colors(n::Int; palette=:default) - Create n distinguishable colors using Makie's default categorical palette (same as AlgebraOfGraphics uses - Wong colors, colorblind-friendly).

Geometry Functions

ChordPlots.arc_pointsFunction
arc_points(start_angle::Real, end_angle::Real, radius::Real; n_points::Int=50)

Generate points along an arc.

Arguments

  • start_angle: Start angle in radians
  • end_angle: End angle in radians
  • radius: Arc radius
  • n_points: Number of points (more = smoother)

Returns

  • Vector{Point2f}: Points along the arc
source
ChordPlots.arc_polygonFunction
arc_polygon(inner_radius::Real, outer_radius::Real, start_angle::Real, end_angle::Real; n_points::Int=30)

Generate a filled arc (annular sector) as a polygon.

Returns points forming a closed polygon: outer arc → inner arc (reversed) → close.

source
ChordPlots.ribbon_pathFunction
ribbon_path(ribbon::Ribbon, radius::Real; n_bezier::Int=30, tension::Real=0.5)

Generate the path for a ribbon connecting two arcs.

The ribbon consists of:

  1. Source arc segment
  2. Bezier curve to target
  3. Target arc segment
  4. Bezier curve back to source

Arguments

  • ribbon: Ribbon geometry specification
  • radius: Radius where ribbons attach
  • n_bezier: Points per Bezier curve
  • tension: Control point tension (0 = straight, 1 = tight curves)
source
ChordPlots.label_positionFunction
label_position(arc::ArcSegment, radius::Real, offset::Real; rotate::Bool=true, justify::Symbol=:inside)

Calculate position for an arc's label.

Arguments

  • arc: Arc segment
  • radius: Outer radius of the arc
  • offset: Distance from arc to label
  • rotate: Whether to rotate label to follow arc
  • justify: Label justification (:inside aligns toward circle center, :outside aligns away)
source
ChordPlots.label_positionsFunction
label_positions(arcs::Vector{ArcSegment{T}}, radius::Real, offset::Real; kwargs...)

Calculate positions for all arc labels.

Keyword Arguments

  • rotate::Bool=true: Whether to rotate labels to follow arcs
  • justify::Symbol=:inside: Label justification (:inside or :outside)
source
ChordPlots.ArcSegmentType
ArcSegment{T<:Real}

Represents an arc on the outer circle for a single label.

Fields

  • label_idx::Int: Index into the label array
  • start_angle::T: Starting angle in radians
  • end_angle::T: Ending angle in radians
  • value::T: Total flow value (determines arc width)
source
ChordPlots.RibbonEndpointType
RibbonEndpoint{T<:Real}

Represents one end of a ribbon attached to an arc.

Fields

  • label_idx::Int: Which label this endpoint is on
  • start_angle::T: Start angle on the arc
  • end_angle::T: End angle on the arc
source
ChordPlots.RibbonType
Ribbon{T<:Real}

Represents a ribbon connecting two labels.

Fields

  • source::RibbonEndpoint{T}: Source endpoint
  • target::RibbonEndpoint{T}: Target endpoint
  • value::T: Co-occurrence value
source

Types

ChordPlots.GroupInfoType
GroupInfo{S<:AbstractString}

Information about a group of labels (e.g., V calls, D calls, J calls).

Fields

  • name::Symbol: Group identifier
  • labels::Vector{S}: Labels belonging to this group
  • indices::UnitRange{Int}: Index range in the combined label list
source

Utility Functions

These functions are exported but don't have separate docstrings:

  • nlabels(cooc) - Number of labels in co-occurrence matrix
  • ngroups(cooc) - Number of groups
  • total_flow(cooc, label_idx) - Total flow for a label (sum of all connections)
  • get_group(cooc, label_idx) - Get group symbol for a label
  • narcs(layout) - Number of arcs in layout
  • nribbons(layout) - Number of ribbons in layout
  • arc_span(arc) - Span angle of an arc
  • arc_midpoint(arc) - Midpoint angle of an arc
  • endpoint_span(endpoint) - Span of a ribbon endpoint
  • endpoint_midpoint(endpoint) - Midpoint of a ribbon endpoint
  • is_self_loop(ribbon) - Check if ribbon is a self-loop
  • resolve_arc_color(scheme, arc, cooc) - Resolve color for an arc
  • resolve_ribbon_color(scheme, ribbon, cooc) - Resolve color for a ribbon
  • chordplot!(ax, cooc; kwargs...) - In-place version of chordplot