A Chord Diagram With ggplot

Using The New ggchord2 Library

stats
dataviz
R
exploring data
Author

Andy Grogan-Kaylor

Published

August 25, 2026

In other earlier posts, I have looked at some ways to get an idea of what scales and demographic variables in my data are related to other scales and demographic variables in my data. One way of visualizing these relationships is a chord diagram.

In this post, I try creating a chord diagram using the fantastic new ggchord2 (Rennie, 2026a, 2026b).

Call Libraries

Show the code
library(faux) # simulated data

library(pander) # nice tables

library(skimr) # descriptive statistics

library(circlize) # circular graphs and chord diagrams

library(scales) # viridis color palettes

library(ggplot2) # beautiful graphs

library(ggchord2) # chord diagrams

Simulated Data

I again simulate some data.

Show the code
set.seed(54321) # random seed

# simulate data

cmat <- c(1.00, 0.30, 0.25, 0.15, 0.15, 0.15,
          0.30, 1.00, 0.00, 0.50, 0.10, 0.15,
          0.25, 0.00, 1.00, 0.50, 0.50, 0.15,
          0.15, 0.50, 0.50, 1.00, 0.00, 0.15,
          0.15, 0.10, 0.50, 0.00, 1.00, 0.15,
          0.15, 0.15, 0.15, 0.15, 0.15, 1.00)

mydata <- rnorm_multi(n = 100, 
                   mu = c(0, 20, 100, 100, 100, 100),
                   sd = c(1, 5, 5, 5, 5, 5),
                   r = cmat, # correlation matrix
                   varnames = c("scaleA", 
                                "scaleB", 
                                "scaleC", 
                                "scaleD", 
                                "scaleE", 
                                "scaleF"),
                   empirical = FALSE)
Show the code
pander(head(mydata)) # nicely formatted table
scaleA scaleB scaleC scaleD scaleE scaleF
1.602 23.34 99.84 97.63 102.1 101.5
1.452 28.85 101.6 99.86 105.9 99.57
0.5092 20.43 105.6 101.7 102.4 101
1.974 21.07 108.3 106.9 102 106.1
-0.9652 17.06 102 106.7 101.5 95.6
0.7906 22.49 104 111.2 96.67 98.47
Show the code
skim(mydata) # descriptive statistics

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
scaleA 0 1 -0.05 1.09 -2.65 -0.80 -0.08 0.65 2.84 ▂▆▇▅▁
scaleB 0 1 20.13 4.70 7.58 16.83 20.32 23.44 29.89 ▁▅▇▆▃
scaleC 0 1 100.11 4.84 88.04 96.77 100.35 102.94 111.84 ▂▃▇▃▂
scaleD 0 1 100.75 4.86 88.29 97.52 100.31 103.65 113.34 ▁▆▇▆▁
scaleE 0 1 100.14 4.95 82.39 97.41 100.81 103.05 112.10 ▁▂▅▇▁
scaleF 0 1 100.24 5.77 86.48 95.77 100.42 103.80 113.96 ▁▇▇▅▂

Chord Diagram

For ggchord to work, I need data on the correlations of different scales, but need this correlation data to be formatted as a list of sources and destinations.

I therefore first create a correlation matrix of my data, and then reformat this correlation matrix as a data frame of sources, destinations, and correlations.

https://www.tutorialspoint.com/ has a page suggesting how to achieve this using Base R.

Show the code
cor_mat <- cor(mydata, # correlation matrix
               use = "complete.obs")

diag(cor_mat) <- 0 # set diagonal to 0

# thanks tutorialspoint.com!
mychorddata <- as.data.frame(as.table(cor_mat))

head(mychorddata) # look at the data
    Var1   Var2      Freq
1 scaleA scaleA 0.0000000
2 scaleB scaleA 0.5407251
3 scaleC scaleA 0.4047779
4 scaleD scaleA 0.2703827
5 scaleE scaleA 0.3092786
6 scaleF scaleA 0.1796353

Using ggchord is then relatively straightforward. I use geom_chord_diagram which adds all of the required geometries of a chord diagram, but could use other geoms to add each geometry separately.

Show the code
# pal_viridis()(5) # 5 viridis colors

ggplot(data = mychorddata, 
       mapping = aes(
         source = Var1,
         target = Var2,
         freq = Freq,
         fill = Var1)) + 
  geom_chord_diagram() + # add all the chord geoms
  # geom_chord_arcs() + # selecting specific 
  # geom_chord_sectors() + # chord geoms allows 
  # geom_chord_labels() + # for more customization
  scale_fill_viridis_d(name = "scale") + # nice colors
  labs(title = "Relationship of Scales In Our Data") +
  theme_void() +
  coord_fixed(clip = "off") # fixed coordinates; don't clip labels
Figure 1: a chord diagram

References

Rennie, N. (2026a). ggchord2: Chord diagrams with ’ggplot2’. https://doi.org/10.32614/CRAN.package.ggchord2
Rennie, N. (2026b). Chord diagrams in R with ‘ggchord2‘. https://nrennie.rbind.io/blog/chord-diagrams-ggchord2/