1

Im learning how to create circular plots in R, similiar to CIRCOS Im using the package circlize to draw links between origin and destination pairs based on if the flight was OB, Inbound and Return. The logic fo the data doesnt really matter, its just a toy example

I have gotten the plot to work based on the code below which works based on the following logic

  1. Take my data, combine destination column with the flight type
  2. Convert to a matrix and feed the origin and the new column into circlize

Reference

library(dplyr)
library(circlize)

# Create Fake Flight Information in a table
orig = c("IE","GB","US","ES","FI","US","IE","IE","GB")
dest = c("FI","FI","ES","ES","US","US","FI","US","IE")
direc = c("IB","OB","RETURN","DOM","OB","DOM","IB","RETURN","IB")
mydf = data.frame(orig, dest, direc)

# Add a column that combines the dest and direction together
mydf <- mydf %>%
  mutate(key = paste(dest,direc)) %>%
  select (orig, key)

# Create a Binary Matrix Based on mydf
mymat <- data.matrix(as.data.frame.matrix(table(mydf)))

# create the objects you want to link from to in your diagram
from <- rownames(mymat)
to <- colnames(mymat)

# Create Diagram by suppling the matrix 
par(mar = c(1, 1, 1, 1))
chordDiagram(mymat, order = sort(union(from, to)), directional = TRUE)
circos.clear()

I like the plot a lot but would like to change it a little bit. For example FI (which is Finland) has 3 measurements on the diagram FI IB, FI OB and FI. I would like to combine them all under FI if possible and distinguish between the three Types of flights using either a colour scheme, Arrows or even adding an additional track which acts as an umbrella for IB OB and RETURN flights

So for Example,

  • FI OB would be placed in FI but have a one way arrow to GB to signify OB
  • FI IB would be placed in FI but have a one way arrow into FI
  • FI RETURN (if it exists) would have a double headed arrow

Can anyone help, Has anyone seen anything similiar been done before? The end result should just have the countries on the plot once so that someone can see very quickly which countries have the most amount of flights

I have tried following other posts but am afraid im getting lost when they move to the more advanced stuff

Thank you very much for your time

Community
  • 1
  • 1
John Smith
  • 2,448
  • 7
  • 54
  • 78

2 Answers2

8

First, I think there is a duplicated record (IE-FI-IB) in your data.

I will first attach the code and figure and then explain a little bit.

df = data.frame(orig, dest, direc, stringsAsFactors = FALSE)
df = unique(df)
col = c("IB" = "red",
        "OB" = "blue",
        "RETURN" = "orange",
        "DOM" = "green")
directional = c("IB" = -1,
                "OB" = 1,
                "RETURN" = 2,
                "DOM" = 0)
diffHeight = c("IB" = -0.04,
                "OB" = 0.04,
                "RETURN" = 0,
                "DOM" = 0)
chordDiagram(df[1:2], col = col[df[[3]]], directional = directional[df[[3]]], 
    direction.type = c("arrows+diffHeight"),
    diffHeight = diffHeight[df[[3]]])

legend("bottomleft", pch = 15, legend = names(col), col = col)

enter image description here

First you need to use the development version of circlize for which you can install it by

devtools::install_github("jokergoo/circlize")

In this new version, chordDiagram() supports input variable as a data frame and drawing two-head arrows for the links (just after reading your post :)).

In above code, col, directional, direction.type and diffHeight can all be set as a vector which corresponds to rows in df.

When directional argument in chordDiagram() is set to 2, the corresponding link will have two directions. Then if direction.type contains arrows, there will be a two-head arrow.

Since diffHeight is a vector which correspond to rows in df, if you want to visualize the direction for a single link both by arrow and offset of the roots, you need to merge these two options as a single string as shown in the example code "arrows+diffHeight".

By default direction for links are from the first column to the second column. But in your case, IB means the reversed direction, so we need to set diffHeight to a negative value to reverse the default direction.

Finally, I observe you have links which start and end in a same sector (ES-ES-DOM and US-US-DOM), you can use self.link argument to control how to represent such self-link. self.link is set to 1 in following figure.

enter image description here

Zuguang Gu
  • 1,301
  • 7
  • 11
  • impressive and very usefull ! I hope John will accept this answer by clicking the V ;^) – irJvV Aug 13 '15 at 06:46
1

Do you need the arrows because the color coding in the graph is telling the From / To story already (FROM -> color edge FROM COUNTRY, TO is color of the FROM COUNTRY arriving at the TO COUNTRY, IF FROM == TO Its own color returns at its own base (see US or ES for example)).

library(dplyr)
library(circlize)

# Create Fake Flight Information in a table
orig = c("IE","GB","US","ES","FI","US","IE","IE","GB")
dest = c("FI","FI","ES","ES","US","US","FI","US","IE")
mydf = data.frame(orig, dest)

# Create a Binary Matrix Based on mydf
mymat <- data.matrix(as.data.frame.matrix(table(mydf)))

# create the objects you want to link from to in your diagram
from <- rownames(mymat)
to <- colnames(mymat)

# Create Diagram by suppling the matrix 
par(mar = c(1, 1, 1, 1))
chordDiagram(mymat, order = sort(union(from, to)), directional = TRUE)
circos.clear()

BY the way -> there is also a OFFSET difference on the edge that tells if it is FROM (wider edge) or TO (smaller edge)

irJvV
  • 892
  • 8
  • 26
  • hi @irJvV, Thank you very much for your suggestion. I think it would be better maybe to have another track outside the track for country that acts as an umbrella to show IB OB and DOM. Its important to be able to differentiate the type of flight for the visualization – John Smith Aug 11 '15 at 14:13
  • Hi John, in what way are you going to use the graph ? As an image, web page or something else ? – irJvV Aug 11 '15 at 14:17
  • As an image. The idea is to show the origin destination pairs and the flight type. For this example, there are only three but in reality there are up to 8 different types of flight. Thank you for the OFFSET, I didn't realize it existed – John Smith Aug 11 '15 at 14:18