Beautiful Chord Diagrams with Flourish

By Kailas Venkitasubramanian in R Data Science Data Visualization

July 8, 2025

There’s a moment in data visualization where a chart stops being a chart and becomes a conversation starter. Chord diagrams do that reliably. Whenever I’ve dropped one into a presentation or a report, someone in the room leans forward. They want to trace the lines. They want to understand what connects to what. That reaction is exactly why I keep coming back to them.

What Is a Chord Diagram?

A chord diagram is a circular visualization that shows relationships between entities. Imagine a circle divided into arcs — each arc represents a category or group. Ribbons stretch between arcs, connecting them. The width of each ribbon encodes the magnitude of the relationship: a thick ribbon means a strong or frequent connection; a thin one means the opposite.

The format has roots in bioinformatics. Martin Krzywinski introduced the Circos software in 2009 specifically to visualize genomic data — chromosome rearrangements, gene overlaps, comparative genomics. The circular layout made sense for genomes, but people quickly realized it worked just as well for any dataset with pairwise relationships. Migration flows. Trade networks. Survey co-responses. The shape traveled fast.

What makes chord diagrams useful — and sometimes irreplaceable — is that they handle complexity that most charts can’t. A matrix with 20 entities has 190 possible pairwise relationships. A heatmap can show them, but you have to work to read it. A chord diagram shows the same information spatially. You see which nodes are highly connected at a glance, and the visual weight of the ribbons tells you something about proportions before you read a single number.

Building Chord Diagrams in Code

If you work in R, Python, or JavaScript, there are solid libraries for this.

In R, the chorddiag package wraps D3 for interactive charts, and circlize gives you fine-grained control over static outputs. The circlize package in particular is well-documented and handles asymmetric flows cleanly — useful when the relationship between A and B is directional.

library(circlize)

mat <- matrix(c(0, 200, 150, 300,
                200, 0, 80, 120,
                150, 80, 0, 90,
                300, 120, 90, 0),
              nrow = 4,
              dimnames = list(c("Group A", "Group B", "Group C", "Group D"),
                              c("Group A", "Group B", "Group C", "Group D")))

chordDiagram(mat)

In Python, holoviews has chord support, and matplotlib can render them with some effort, but the most practical route is chord from the PyPI package of the same name, or going through plotly for interactive output.

from chord import Chord

matrix = [
    [0, 200, 150, 300],
    [200, 0, 80, 120],
    [150, 80, 0, 90],
    [300, 120, 90, 0]
]

names = ["Group A", "Group B", "Group C", "Group D"]
Chord(matrix, names).to_html("chord.html")

In JavaScript, D3.js is the go-to. The d3-chord module handles the layout math, and you bring your own rendering. It takes more setup than a library call, but D3 gives you control over every pixel if you need it.

import * as d3 from "d3";

const matrix = [
  [0, 200, 150, 300],
  [200, 0, 80, 120],
  [150, 80, 0, 90],
  [300, 120, 90, 0]
];

const chord = d3.chord().padAngle(0.05)(matrix);
// Render arcs and ribbons with d3 path generators

Each of these paths gets you to a working diagram. The tradeoff is always between ease and control.

Where Chord Diagrams Actually Get Used

In social science research, chord diagrams show up in a few recurring contexts.

Migration and mobility studies use them to map flows between regions — where people moved from, where they went, in what volumes. The Pew Research Center has published chord diagrams showing international migration between world regions, and they communicate regional pull-push dynamics in a way that tables simply don’t.

Survey and co-occurrence analysis is another fit. If you’re analyzing which political issues respondents co-prioritize, or which program services clients use together, the chord layout shows clustering patterns that a bar chart misses.

Network and referral tracking in public health, social services, and administrative data work is where I’ve personally found them most useful. Who is connected to whom, through which systems, in what proportions.

Trade and economic flow analysis uses them to show import/export relationships between countries or sectors. The visual makes it obvious which economies are central versus peripheral in a network.

Flourish: The Practical Choice

Coding chord diagrams from scratch works, but it’s not always the right tool. When I’m preparing something for a public report — something that needs to be embedded, shareable, and readable by a non-technical audience — I use Flourish.

Flourish is a browser-based data visualization platform. You upload or paste your data, configure the chart, and get an embeddable output. No code deployment, no hosting concerns, no dependency management. The chord template is clean and interactive by default: hover to highlight individual ribbons, click to isolate a node.

For our State of our Data Report at the Charlotte Regional Data Trust, I used Flourish to build a chord diagram that showed how people and households appear across different administrative databases — Medicaid, housing assistance, child welfare, employment records, and others. The question we were trying to answer visually was: what does the overlap look like? Which systems share the most records? Which populations appear in multiple databases simultaneously?

The visualization landed differently than I expected. It became one of the most-referenced figures in the report. People who wouldn’t normally engage with data tables spent time with it, tracing connections between systems. That’s the thing about chord diagrams — they invite exploration in a way that passive charts don’t.

How I Built It in Flourish

The workflow is straightforward once you understand the data format Flourish expects.

Step 1: Prepare your data as a matrix. Flourish takes a square matrix where rows and columns represent the same set of entities. Each cell value is the weight of the connection between that row and column. In our case, rows and columns were administrative databases, and cell values were counts of individuals appearing in both.

Medicaid Housing Child Welfare Employment
Medicaid 4,200 1,800 6,100
Housing 4,200 900 2,300
Child Welfare 1,800 900 700
Employment 6,100 2,300 700

Step 2: Upload to Flourish. Create a new visualization, select the Chord Diagram template, and paste your matrix into the data editor. Flourish reads the row/column headers automatically as node labels.

Step 3: Configure visual settings. Choose your color palette — I went with colors that matched the report’s design system. Adjust the padding between arcs, the label font size, and whether to show the ribbon labels on hover. Flourish’s settings panel is well-organized; you won’t spend long hunting for options.

Step 4: Embed. Flourish generates a public URL and an iframe embed code. Drop it into your website, your report CMS, or your slides. The chart is interactive out of the box — no extra configuration needed.

One thing worth knowing: Flourish’s free tier puts a Flourish watermark on the embed. If you’re publishing officially, the team or business plan removes it. For internal prototyping, the free tier is fine.

A Note on When Not to Use Them

Chord diagrams get cluttered when you have more than about 12–15 nodes. Beyond that, the ribbons start overlapping and the chart becomes hard to read. If you’re working with a large network, consider grouping nodes before visualizing, or use a force-directed graph instead.

They also assume the relationships are symmetric or, if directional, that directionality can be encoded through arc sizing. They’re not a good fit for hierarchical data or time series — other chart types handle those better.


If you haven’t tried chord diagrams yet, I’d suggest starting with Flourish just to build the intuition. Get comfortable with what the shape communicates, then decide if you need code-level control for your actual project. The visualization type is genuinely useful, and once you’ve used it for the right dataset, you’ll recognize that dataset again when you see it.