Search code examples
rvisualization

How to fade out part of a chord diagram?


I have a data frame with the origin and destination regions of different species. I want to create multiple chord diagrams, each one concentrating in one of each origin regions, and blending out the other ones in grey for better visibility.

It should look something like this:

Example result, source: Wong et al. 2023

This is an example of the data, as well as the code to create the chord diagram, but I haven't had success in finding out how to blend out the other regions and only show one of them.

df <- structure(list(taxonID = c(22275L, 34240L, 25006L, 23833L, 25803L, 
27617L, 34141L, 19964L, 20100L, 26613L, 26861L, 23826L, 29611L, 
9594L, 16628L, 22702L, 24580L, 30677L, 24007L, 30670L, 26848L, 
26628L, 33202L, 34287L, 23042L, 21088L, 34013L, 18690L, 33110L, 
21530L, 16628L, 19257L, 31259L, 6250L, 26392L, 20276L, 28572L, 
14840L, 20978L, 30560L, 34507L, 12459L, 33842L, 35277L, 16661L, 
18430L, 28163L, 29207L, 24587L, 29611L, 23657L, 27543L, 30897L, 
27253L, 26101L, 24761L, 18720L, 19602L, 34358L, 9232L, 32993L, 
19218L, 26844L, 24059L, 20086L, 32392L, 35067L, 9554L, 25080L, 
24743L, 25152L, 35296L, 13681L, 18391L, 26699L, 26466L, 26786L, 
11539L, 29325L, 16559L, 11983L, 29815L, 18391L, 30955L, 22044L, 
9924L, 17501L, 30389L, 17179L, 6725L, 18946L, 12267L, 11389L, 
9157L, 18764L, 16721L, 23583L, 18718L, 18783L, 12199L), origin = c("Sub-Saharan Africa", 
"Sub-Saharan Africa", "Europe", "South America", "East Asia", 
"West Asia", "East Asia", "East Asia", "South Asia", "East Asia", 
"South Asia", "Pacific", "West Asia", "East Asia", "South America", 
"South Asia", "Europe", "Europe", "Central America and the Caribbean", 
"West Asia", "West Asia", "South America", "North America", "Central America and the Caribbean", 
"West Asia", "Europe", "Sub-Saharan Africa", "West Asia", "South Asia", 
"South America", "Europe", "South America", "Sub-Saharan Africa", 
"Europe", "Europe", "Saharo-Arabia", "Central America and the Caribbean", 
"North America", "Sub-Saharan Africa", "Central America and the Caribbean", 
"South America", "Saharo-Arabia", "West Asia", "Europe", "Central America and the Caribbean", 
"West Asia", "Central America and the Caribbean", "Saharo-Arabia", 
"Sub-Saharan Africa", "West Asia", "West Asia", "West Asia", 
"Sub-Saharan Africa", "Saharo-Arabia", "Europe", "East Asia", 
"Central America and the Caribbean", "South Asia", "North America", 
"North America", "Central America and the Caribbean", "Central America and the Caribbean", 
"Saharo-Arabia", "North America", "Pacific", "North America", 
"South America", "Saharo-Arabia", "Sub-Saharan Africa", "Europe", 
"Europe", "Saharo-Arabia", "Australasia", "Australasia", "Europe", 
"South Asia", "Saharo-Arabia", "South Asia", "Sub-Saharan Africa", 
"Australasia", "Saharo-Arabia", "West Asia", "Saharo-Arabia", 
"South America", "West Asia", "East Asia", "Saharo-Arabia", "Sub-Saharan Africa", 
"South Asia", "South Asia", "Europe", "West Asia", "West Asia", 
"Saharo-Arabia", "South Asia", "South Asia", "North America", 
"Central America and the Caribbean", "South Asia", "Sub-Saharan Africa"
), dest = c("Europe", "Australasia", "North America", "South America", 
"East Asia", "Sub-Saharan Africa", "East Asia", "South America", 
"Australasia", "Sub-Saharan Africa", "Saharo-Arabia", "South America", 
"Pacific", "Pacific", "Europe", "West Asia", "North America", 
"Australasia", "East Asia", "North America", "Australasia", "Australasia", 
"North America", "Europe", "Sub-Saharan Africa", "North America", 
"South America", "South America", "Sub-Saharan Africa", "Pacific", 
"Saharo-Arabia", "North America", "Australasia", "South Asia", 
"Europe", "Central America and the Caribbean", "Central America and the Caribbean", 
"Europe", "Sub-Saharan Africa", "Australasia", "North America", 
"Europe", "Pacific", "Sub-Saharan Africa", "Sub-Saharan Africa", 
"Sub-Saharan Africa", "Central America and the Caribbean", "West Asia", 
"North America", "North America", "Europe", "North America", 
"Sub-Saharan Africa", "Saharo-Arabia", "North America", "Sub-Saharan Africa", 
"North America", "Saharo-Arabia", "Saharo-Arabia", "Europe", 
"Australasia", "South America", "Europe", "Antarctic", "Pacific", 
"South Asia", "Australasia", "East Asia", "Central America and the Caribbean", 
"South Asia", "Europe", "Europe", "West Asia", "West Asia", "Europe", 
"South America", "East Asia", "North America", "Europe", "South Asia", 
"Europe", "West Asia", "Saharo-Arabia", "Australasia", "Europe", 
"Europe", "Saharo-Arabia", "Europe", "Europe", "South Asia", 
"Europe", "Saharo-Arabia", "West Asia", "North America", "Sub-Saharan Africa", 
"Pacific", "Australasia", "South Asia", "Europe", "Central America and the Caribbean"
)), row.names = c(NA, -100L), class = c("data.table", "data.frame"
))

Plotting code:

adjacencyData <- with(df, table(origin, dest))
circlize::chordDiagram(adjacencyData, transparency = 0.5)

Any idea on how to achieve something like that?


Solution

  • You can control the colors using the grid.col function in chordDiagram. You can create a named vector that includes all the regions in the table data (adjacencyData) of all grey, then iterate through each one and change each region to a color (here, red) using 'lapply':

    all_areas <- union(rownames(adjacencyData), colnames(adjacencyData))
    greygrid <- setNames(rep("grey", length(all_areas)), all_areas)
    
    par(mfrow = c(3,4))
    
    lapply(all_areas, \(xx){
      greygrid[xx] <- "red"
      chordDiagram(adjacencyData, transparency = 0.5,
                   grid.col = greygrid)
      title(xx)
    })
    

    enter image description here

    Note I used the par() command to create this 3x4 figure to demonstrate for this answer. If you leave that out, it will create 12 individual figures. You could also export them individually using pdf, etc.

    Edit

    Based on the comment:

    Do you know if it is also possible to show not only the outgoing links for each region, but also the incoming ones, perhaps in another color?

    Yes this is possible by creating a matrix of colors for use with the col function and modifying the original named vector (greygrid) since it will be cleared to highlight the perimeter as well:

    # initiate vector and grid of all grey 
    all_areas <- union(rownames(adjacencyData), colnames(adjacencyData))
    greygrid <- setNames(rep("grey", length(all_areas)), all_areas)
    grey_mat <- matrix("grey", length(adjacencyData), 
                       ncol = ncol(adjacencyData),
                       nrow = nrow(adjacencyData),
                       dimnames = list(rownames(adjacencyData), colnames(adjacencyData)))
    
    ### plot
    par(mfrow = c(3,4))
    
    lapply(all_areas, \(origin){
      # perimeter colors
      greygrid[names(adjacencyData[,origin][adjacencyData[,origin] > 0])] <- "blue"
      greygrid[origin] <- "red"
      # chord colors
      grey_mat[,which(colnames(grey_mat) == origin)] <- "blue"
      grey_mat[which(rownames(grey_mat) == origin),] <- "red"
      
      chordDiagram(adjacencyData, transparency = 0.5,
                   grid.col = greygrid,
                   col = grey_mat)
      title(origin)
    })
    

    enter image description here