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,toandvalue), or a square numeric matrix of flows with row and/or column names, wheredata[i, j]is the flow from entityito entityj. 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
datais a data frame. Defaults to"from".- to
The name of the column holding the destination of each flow. Only used when
datais a data frame. Defaults to"to".- value
The name of the numeric (non-negative) column holding the size of each flow. Use
NULLto count rows (every row counts as 1). Only used whendatais a data frame. Defaults to"value".- directed
Whether flows are directed. When
TRUE(default),A -> BandB -> Aare kept apart, so a ribbon can be wider at one end than at the other. WhenFALSE, 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 toNULL.- colorPalette
D3 categorical color scheme used when
colorsisNULL(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.
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"
)