API Reference
Complete reference for all exported functions and types.
Main Functions
ChordPlots.cooccurrence_matrix — Function
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 datacolumns::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])ChordPlots.chordplot — Function
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 ribbonsouter_radius = 1.0: Outer radius for arcsarc_width = 0.08: Width of arc segments
Arc and gap layout
gap_fraction = 0.03: Fraction of circle reserved for gapsarc_scale = 1.0: Scale for arc portion; < 1 adds extra gapssort_by = :group: Order arcs by:group,:value, or:nonelabel_order = nothing: Fixed order (overridessort_by)
Ribbon appearance
ribbon_width_power = 1.0: Exponent for ribbon widthmin_ribbon_value = 0: Hide ribbons below this valueribbon_tension = 0.5: Bezier curve tension
Arc appearance
arc_strokewidth = 0.5: Border widtharc_strokecolor = :black: Border color
Labels
show_labels = true: Whether to show labelslabel_offset = 0.12: Distance from arc to labellabel_fontsize = 10: Font sizelabel_color = :black: Color (use:groupfor category colors)rotate_labels = true: Rotate labels to follow arcslabel_justify = :inside::insideor:outsidemin_arc_flow = 0: Hide arcs below this flow
Colors
colorscheme = :group: Color scheme (:group,:categorical, orAbstractColorScheme)
Opacity (unified)
alpha = 1.0: Base opacity per component (ribbons, arcs, labels). AcceptsReal,Tuple, orComponentAlpha. Scaling off = fixed opacity; scaling on = upper bound (min_alpha to this).alpha_by_value = false: Value-based scaling. AcceptsBoolorValueScaling. 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_alphato the component’s basealpha; off → opacity is that component base alpha (fixed). falseor unknown → no scaling (all components 1.0).true→ all components scaled.ValueScaling(; components=(ribbons=..., arcs=..., labels=...))→ per-component.
- For each component (ribbons, arcs, labels), on → opacity scales by value from
Focus (highlight subset)
focus_group = nothing: Group to apply focus stylingfocus_labels = nothing: Labels to keep highlighteddim_color = RGB(0.55, 0.55, 0.55): Color for dimmed elementsdim_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)
))chordplot(df::DataFrame, columns; kwargs...)Create chord plot directly from DataFrame.
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.
ChordPlots.compute_layout — Function
compute_layout(cooc::AbstractChordData, config::LayoutConfig=LayoutConfig())Compute the complete layout for a chord diagram.
Algorithm
- Calculate total flow for each label
- Allocate angular width proportional to flow
- Assign arc positions
- Generate ribbon endpoints based on co-occurrence values
Data Types
ChordPlots.AbstractChordData — Type
AbstractChordDataAbstract supertype for chord data (co-occurrence or normalized/frequency).
All subtypes must have fields: matrix, labels, groups, label_to_index. Use CoOccurrenceMatrix for raw counts; use NormalizedCoOccurrenceMatrix for frequencies or combined data (e.g. mean of normalized matrices from multiple sources).
ChordPlots.CoOccurrenceMatrix — Type
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 labelsgroups::Vector{GroupInfo{S}}: Group informationlabel_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 countChordPlots.NormalizedCoOccurrenceMatrix — Type
NormalizedCoOccurrenceMatrix{T<:Real, S<:AbstractString} <: AbstractChordDataCo-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).
Data Management
ChordPlots.filter_top_n — Function
filter_top_n(cooc::AbstractChordData, n::Int)Keep only the top n labels by total flow. Returns the same type as cooc.
ChordPlots.filter_by_threshold — Function
filter_by_threshold(cooc::AbstractChordData, min_value)Create a new matrix with values below threshold set to zero. Returns the same type as cooc.
ChordPlots.normalize — Function
normalize(cooc::CoOccurrenceMatrix) -> NormalizedCoOccurrenceMatrixReturn a normalized version where all values sum to 1. Use for comparing matrices from different sample sizes or before combining multiple sources.
normalize(cooc::NormalizedCoOccurrenceMatrix)Return copy unchanged (already normalized).
ChordPlots.mean_normalized — Function
mean_normalized(coocs::AbstractVector{<:AbstractChordData}) -> NormalizedCoOccurrenceMatrixCombine 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.
ChordPlots.expand_labels — Function
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)Comparison
Base.diff — Function
diff(a::AbstractChordData, b::AbstractChordData; absolute=false) -> NormalizedCoOccurrenceMatrixCompute 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: Iftrue, return absolute differences|a - b|(all positive, thickest ribbons = biggest changes). Iffalse(default), return signed differences (positive wherea > b, negative wherea < b) — use withdiverging_colorsordiff_colorsto 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
Data Exploration
Inspect the distribution of co-occurrence values to choose thresholds (e.g. min_ribbon_value, filter_by_threshold):
ChordPlots.cooccurrence_values — Function
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.
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.
ChordPlots.value_histogram — Function
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.
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!.
Layout Functions
ChordPlots.filter_ribbons — Function
filter_ribbons(layout::ChordLayout, min_value::Real)Filter ribbons below a minimum value threshold.
ChordPlots.filter_ribbons_top_n — Function
filter_ribbons_top_n(layout::ChordLayout, n::Int)Keep only the top n ribbons by value.
ChordPlots.label_order — Function
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 inchordplot(: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)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 (:groupkeeps groups together sorted by flow,:valuesorts all by flow,:noneuses union order).include_all::Bool = true: Iftrue, include all labels from the union (labels missing in some matrices contribute zero flow). Iffalse, 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)ChordPlots.LayoutConfig — Type
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 attachmentouter_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 whenlabel_orderis set.label_order::Union{Nothing, Vector{Int}}: If set, fixed order of label indices on the circle (overridessort_by)
Ribbon thickness
ribbon_width_power::T: Exponent for ribbon width (value/flow)^power; > 1 makes thick vs thin more dramatic
ChordPlots.ChordLayout — Type
ChordLayout{T<:Real}Complete layout information for rendering a chord diagram.
Fields
arcs::Vector{ArcSegment{T}}: Arc segments for each labelribbons::Vector{Ribbon{T}}: All ribbonsinner_radius::T: Inner radius for ribbonsouter_radius::T: Outer radius for arcsgap_angle::T: Gap between adjacent arcs
Opacity Configuration
ChordPlots.ComponentAlpha — Type
ComponentAlphaNamed 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 separatelyComponentAlpha(v): Set all components to the same valueComponentAlpha((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))ChordPlots.ValueScaling — Type
ValueScalingValue-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 fromalpha(strongest). - Off (false): opacity is the component's base alpha from
alpha(fixed; no scaling). Usealpha=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::linearor:logscaling.
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)))Color Functions
ChordPlots.group_colors — Function
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 (:defaultfor Makie/AoG palette,:modernfor custom)
ChordPlots.gradient_colors — Function
gradient_colors(; colormap=:viridis, min_val=0.0, max_val=1.0)Create a gradient-based color scheme.
ChordPlots.diverging_colors — Function
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 connectionsChordPlots.diff_colors — Function
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))ChordPlots.with_alpha — Function
with_alpha(color::Colorant, alpha::Real)Return color with specified alpha value.
ChordPlots.darken — Function
darken(color::Colorant, factor::Real=0.2)Darken a color by the given factor.
ChordPlots.lighten — Function
lighten(color::Colorant, factor::Real=0.2)Lighten a color by the given factor.
ChordPlots.GroupColorScheme — Type
GroupColorScheme{C<:Colorant}Assigns colors based on label groups.
Fields
group_colors::Dict{Symbol, C}: Color for each groupdefault_color::C: Fallback color
ChordPlots.CategoricalColorScheme — Type
CategoricalColorScheme{C<:Colorant}Assigns distinct colors to each label.
Fields
colors::Vector{C}: Color palette
ChordPlots.GradientColorScheme — Type
GradientColorSchemeColors based on a gradient (e.g., by value).
Fields
colormap::Symbol: Makie colormap namerange::Tuple{Float64, Float64}: Value range for mapping
ChordPlots.DivergingColorScheme — Type
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 valuespositive_color::C: Color for positive values (enrichment)range::Tuple{Float64, Float64}: (min, max) value range for normalizationsymmetric::Bool: If true, range is symmetric around zero (max absolute value)
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_points — Function
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 radiansend_angle: End angle in radiansradius: Arc radiusn_points: Number of points (more = smoother)
Returns
Vector{Point2f}: Points along the arc
ChordPlots.arc_polygon — Function
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.
ChordPlots.ribbon_path — Function
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:
- Source arc segment
- Bezier curve to target
- Target arc segment
- Bezier curve back to source
Arguments
ribbon: Ribbon geometry specificationradius: Radius where ribbons attachn_bezier: Points per Bezier curvetension: Control point tension (0 = straight, 1 = tight curves)
ChordPlots.ribbon_paths — Function
ribbon_paths(ribbons::Vector{Ribbon{T}}, radius::Real; kwargs...)Generate paths for multiple ribbons.
ChordPlots.label_position — Function
label_position(arc::ArcSegment, radius::Real, offset::Real; rotate::Bool=true, justify::Symbol=:inside)Calculate position for an arc's label.
Arguments
arc: Arc segmentradius: Outer radius of the arcoffset: Distance from arc to labelrotate: Whether to rotate label to follow arcjustify: Label justification (:insidealigns toward circle center,:outsidealigns away)
ChordPlots.label_positions — Function
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 arcsjustify::Symbol=:inside: Label justification (:insideor:outside)
ChordPlots.ArcSegment — Type
ArcSegment{T<:Real}Represents an arc on the outer circle for a single label.
Fields
label_idx::Int: Index into the label arraystart_angle::T: Starting angle in radiansend_angle::T: Ending angle in radiansvalue::T: Total flow value (determines arc width)
ChordPlots.RibbonEndpoint — Type
RibbonEndpoint{T<:Real}Represents one end of a ribbon attached to an arc.
Fields
label_idx::Int: Which label this endpoint is onstart_angle::T: Start angle on the arcend_angle::T: End angle on the arc
ChordPlots.Ribbon — Type
Ribbon{T<:Real}Represents a ribbon connecting two labels.
Fields
source::RibbonEndpoint{T}: Source endpointtarget::RibbonEndpoint{T}: Target endpointvalue::T: Co-occurrence value
Types
ChordPlots.GroupInfo — Type
GroupInfo{S<:AbstractString}Information about a group of labels (e.g., V calls, D calls, J calls).
Fields
name::Symbol: Group identifierlabels::Vector{S}: Labels belonging to this groupindices::UnitRange{Int}: Index range in the combined label list
Utility Functions
These functions are exported but don't have separate docstrings:
nlabels(cooc)- Number of labels in co-occurrence matrixngroups(cooc)- Number of groupstotal_flow(cooc, label_idx)- Total flow for a label (sum of all connections)get_group(cooc, label_idx)- Get group symbol for a labelnarcs(layout)- Number of arcs in layoutnribbons(layout)- Number of ribbons in layoutarc_span(arc)- Span angle of an arcarc_midpoint(arc)- Midpoint angle of an arcendpoint_span(endpoint)- Span of a ribbon endpointendpoint_midpoint(endpoint)- Midpoint of a ribbon endpointis_self_loop(ribbon)- Check if ribbon is a self-loopresolve_arc_color(scheme, arc, cooc)- Resolve color for an arcresolve_ribbon_color(scheme, ribbon, cooc)- Resolve color for a ribbonchordplot!(ax, cooc; kwargs...)- In-place version ofchordplot