A chord diagram is a graphical method of displaying the inter-relationships between data in a matrix. The data are arranged radially around a circle with the relationships between the data points typically drawn as arcs connecting the data (Wikipedia).

The chorddiag package in R allows to create interactive chord diagrams using the JavaScript visualization library D3 from within R using the htmlwidgets interfacing framework.

In this blog post, we will see how to create interactive chord diagrams. You can hover over the arcs for each of the courses/sections below and see how many students from each section are taking each course.

library(chorddiag)

students = data.frame(Math = c(50, 25, 5, 12),
                      Art = c(10, 55, 5, 20),
                      Science = c(45,12,29, 20),
                      PE = c(24,67,27,15))

students = as.matrix(students)
row.names(students) = c("Section A", "Section B", "Section C", "Section D")

chorddiag(students, type = "bipartite", showTicks = F, groupnameFontsize = 14, groupnamePadding = 10, margin = 90)



We can also use chord diagrams to visualize transition matrices. In the dummy data below, let’s assume each row is the number of customers each company has this year. However, next year, let’s say some of the customers will move to new companies (shown in the columns). Assume this matrix as a transition matrix in a marchov-chain. You can hover over the visualization and see which companies are losing the most and which ones are retaining more customers.

suppressMessages(library(tidyverse))
Warning in sample.int(.Machine$integer.max - 1L, 1L): '.Random.seed' is not
an integer vector but of type 'NULL', so ignored
df = data_frame(`Company A` = c(800, 200, 100, 50, 140, 200, 140),
                `Company B` = c(100, 2000, 300, 400, 50, 0, 290),
                `Company C` = c(200, 500, 4000, 80, 120, 320, 600),
                `Company D` = c(500, 200, 300, 5000, 250, 140, 450),
                `Company E` = c(600, 300, 150, 600, 6000, 30, 0),
                `Company F` = c(500, 400, 100, 300, 250, 4500, 140),
                `Company G` = c(300, 50, 0, 150, 600, 250, 7000))
df = as.matrix(df)
row.names(df) = c(colnames(df))
df
          Company A Company B Company C Company D Company E Company F
Company A       800       100       200       500       600       500
Company B       200      2000       500       200       300       400
Company C       100       300      4000       300       150       100
Company D        50       400        80      5000       600       300
Company E       140        50       120       250      6000       250
Company F       200         0       320       140        30      4500
Company G       140       290       600       450         0       140
          Company G
Company A       300
Company B        50
Company C         0
Company D       150
Company E       600
Company F       250
Company G      7000
chorddiag(df, type = "directional", showTicks = F, groupnameFontsize = 14, groupnamePadding = 10, margin = 90)



Chord Diagrams in Shiny


we can also embede shiny chord diagrams for more interactivity. The shiny app below is similar to the one shown above, but now we are looking over different markets.




The code for the above shiny app is below.

ui

library(shiny)
library(chorddiag)

shinyUI(fluidPage(
  br(),
  br(),
  radioButtons('select_market',"Select Market",inline = TRUE,
               choices = c("East","West","South","North"),
               selected = 'East'),
  
  chorddiagOutput("distPlot", height = 600)
))

server

library(shiny)
library(chorddiag)

set.seed(1)   # for reproducibility
df_east = matrix(sample(seq(100, 5000, 50), 49), ncol = 7)
row.names(df_east) = c("Company A" ,"Company B" ,"Company C" ,"Company D","Company E", "Company F" ,"Company G")
colnames(df_east) = row.names(df_east)

set.seed(2)  
df_west = matrix(sample(seq(100, 5000, 50), 49), ncol = 7)
colnames(df_west) = row.names(df_east)
row.names(df_west) = row.names(df_east)


set.seed(3)   
df_south = matrix(sample(seq(100, 5000, 50), 49), ncol = 7)
colnames(df_south) = row.names(df_east)
row.names(df_south) = row.names(df_east)

set.seed(4)  
df_north = matrix(sample(seq(100, 5000, 50), 49), ncol = 7)
colnames(df_north) = row.names(df_east)
row.names(df_north) = row.names(df_east)


shinyServer(function(input, output) {
   

  output$distPlot <- renderChorddiag({
    
       if(input$select_market =="East"){
         chorddiag(df_east, showTicks = F, groupnameFontsize = 14, groupnamePadding = 10, margin = 90)
       }else if(
        input$select_market =="West"){
        chorddiag(df_west, showTicks = F, groupnameFontsize = 14, groupnamePadding = 10, margin = 90)
       } else if(
         input$select_market =="South"){
         chorddiag(df_south, showTicks = F, groupnameFontsize = 14, groupnamePadding = 10, margin = 90)
       }else{
         chorddiag(df_north, showTicks = F, groupnameFontsize = 14, groupnamePadding = 10, margin = 90)
       }
    
  })
  
})