Skip to contents

A chord diagram shows the flows (or connections) between a set of entities arranged around a circle. Each entity is drawn as an outer arc whose length is proportional to the total flow it is involved in, and each pair of entities is linked by a ribbon whose width at either end is proportional to the flow in that direction. Chord diagrams are a compact way to display migration, trade, transitions between states, or any other square matrix of flows.

The look and feel are inspired by the chord chart of the Nivo visualization library, reimplemented in plain D3. The chart is interactive: hovering an arc (or its label) keeps the ribbons connected to that entity and fades out all the others, while a tooltip lists the entity's totals and its largest flows. Hovering a ribbon isolates it and shows the flow in both directions. Clicking an arc pins its highlight; clicking it again, or clicking the background, releases it.

Usage

chord_diagram(
  data,
  from = "from",
  to = "to",
  value = "value",
  directed = TRUE,
  colors = NULL,
  colorPalette = "Tableau10",
  ribbonColor = c("source", "target", "gradient"),
  sortGroups = c("none", "descending", "ascending"),
  padAngle = 0.03,
  innerRadiusRatio = 0.92,
  arcOpacity = 1,
  ribbonOpacity = 0.6,
  fadeOpacity = 0.1,
  strokeWidth = 0.5,
  showLabels = TRUE,
  rotateLabels = FALSE,
  labelFontSize = 11,
  labelOffset = 10,
  valueFormat = ",~f",
  hover = TRUE,
  animate = TRUE,
  title = NULL,
  titleFontSize = 16,
  font = "Verdana, Geneva, Tahoma, sans-serif",
  bgcol = "white",
  textCol = "black",
  width = NULL,
  height = NULL
)

Arguments

data

Either a data frame in edge-list format (one row per flow, with the columns named by from, to and value), or a square numeric matrix of flows with row and/or column names, where data[i, j] is the flow from entity i to entity j. Duplicated edges are summed. Self-flows (from == to) are allowed.

from

The name of the column holding the origin of each flow. Only used when data is a data frame. Defaults to "from".

to

The name of the column holding the destination of each flow. Only used when data is a data frame. Defaults to "to".

value

The name of the numeric (non-negative) column holding the size of each flow. Use NULL to count rows (every row counts as 1). Only used when data is a data frame. Defaults to "value".

directed

Whether flows are directed. When TRUE (default), A -> B and B -> A are kept apart, so a ribbon can be wider at one end than at the other. When FALSE, flows are treated as undirected links: in an edge list, both directions are summed; a symmetric matrix is used as is, and a non-symmetric one is symmetrized by adding its transpose (the diagonal is left unchanged).

colors

Optional. A vector of colors for the entities, recycled if needed. A named vector maps colors to entity names (unnamed entities fall back to colorPalette). Defaults to NULL.

colorPalette

D3 categorical color scheme used when colors is NULL (e.g. "Tableau10", "Category10", "Set2", "Dark2", "Paired"). Defaults to "Tableau10".

ribbonColor

How ribbons are colored: "source" (default, the color of the entity with the larger outgoing flow of the pair), "target", or "gradient" (a gradient from one entity's color to the other's).

sortGroups

Order of the arcs around the circle: "none" (default, the order of first appearance in the edge list, the factor levels, or the matrix order), "descending" or "ascending" (by total flow).

padAngle

Gap between adjacent arcs, in radians. Defaults to 0.03.

innerRadiusRatio

Inner radius of the arcs as a fraction of their outer radius (between 0.5 and 0.99). Larger values give thinner arcs. Defaults to 0.92.

arcOpacity

Fill opacity of the arcs (0 to 1). Defaults to 1.

ribbonOpacity

Fill opacity of the ribbons (0 to 1). Defaults to 0.6.

fadeOpacity

Opacity of the ribbons and arcs that are faded out while another element is hovered (0 to 1). Defaults to 0.1.

strokeWidth

Width of the arc and ribbon borders in pixels (the border uses a darker shade of the fill). Defaults to 0.5.

showLabels

Whether to display the entity names outside the arcs. Labels of arcs too small to hold them are hidden. Defaults to TRUE.

rotateLabels

Whether to orient the labels along the radius of the circle (useful with many entities). When FALSE (default), labels are horizontal.

labelFontSize

Font size of the labels. Defaults to 11.

labelOffset

Distance in pixels between the arcs and their labels. Defaults to 10.

valueFormat

A d3-format specifier used to display values in the tooltip (e.g. ",.0f", ".2s", "$,.1f"). Defaults to ",~f".

hover

Whether hovering highlights arcs and ribbons and shows a tooltip, and clicking an arc pins its highlight. Defaults to TRUE.

animate

Whether the arcs sweep in and the ribbons fade in on first render. Defaults to TRUE.

title

Optional. Title of the chart.

titleFontSize

Font size of the chart title. Defaults to 16.

font

The font family used for all text. Defaults to "Verdana, Geneva, Tahoma, sans-serif".

bgcol

Background color of the SVG. Defaults to "white".

textCol

Color of the title and the labels. Defaults to "black".

width

Optional. The width of the SVG output.

height

Optional. The height of the SVG output.

Value

An SVG chord diagram.

Examples

# Edge list: hypothetical migration flows between regions (thousands)
migration <- data.frame(
  from  = c("Africa", "Africa", "Africa", "Asia", "Asia", "Asia",
            "Europe", "Europe", "Latin America", "Latin America",
            "North America", "Oceania", "Asia", "Europe"),
  to    = c("Europe", "North America", "Asia", "Europe", "North America",
            "Oceania", "North America", "Asia", "North America", "Europe",
            "Europe", "Asia", "Africa", "Oceania"),
  value = c(420, 150, 90, 610, 520, 230, 180, 120, 870, 260,
            95, 40, 60, 75)
)

chord_diagram(
  data        = migration,
  from        = "from",
  to          = "to",
  value       = "value",
  valueFormat = ",.0f",
  title       = "Migration flows between regions (thousands)"
)
# Square matrix with dimnames: the classic hair-color transition data hair <- matrix( c(11975, 5871, 8916, 2868, 1951, 10048, 2060, 6171, 8010, 16145, 8090, 8045, 1013, 990, 940, 6907), nrow = 4, byrow = TRUE, dimnames = list(c("Black", "Blond", "Brown", "Red"), c("Black", "Blond", "Brown", "Red")) ) chord_diagram( data = hair, colors = c("#3b3b3b", "#f2c45a", "#8c5a3c", "#d0533a"), ribbonColor = "gradient", padAngle = 0.05, valueFormat = ",.0f", title = "Hair color flows" )
# Undirected co-authorship links between departments, on a dark background coauthors <- data.frame( from = c("Biology", "Biology", "Biology", "Chemistry", "Chemistry", "Physics", "Physics", "Mathematics", "Computer Science", "Computer Science", "Medicine", "Medicine"), to = c("Chemistry", "Medicine", "Computer Science", "Physics", "Medicine", "Mathematics", "Computer Science", "Computer Science", "Medicine", "Biology", "Chemistry", "Physics"), value = c(34, 51, 18, 27, 22, 30, 25, 41, 16, 12, 9, 6) ) chord_diagram( data = coauthors, directed = FALSE, sortGroups = "descending", colorPalette = "Set2", ribbonOpacity = 0.7, bgcol = "#1e1e2e", textCol = "#f0f0f0", title = "Joint publications between departments" )