Updated Circular Plots for Directional Bilateral Migration Data

I have had a few emails recently regarding plots from my new working paper on global migration flows, which has received some media coverage here, here and here. The plots were created using Zuguang Gu’s excellent circlize package and are a modified version of those discussed in an earlier blog post. In particular, I have made four changes:

  1. I have added arrow heads to better indicate the direction of flows, following the example in Scientific American.
  2. I have reorganized the sectors on the outside of the circle so that in each the outflows are plotted first (largest to smallest) followed by the inflows (again, in size order). I prefer this new layout (previously the inflows were plotted first) as it allows the time sequencing of migration events (a migrant has to leave before they can arrive) to match up with the natural tendency for most to read from left to right.
  3. I have cut out the white spaces that detached the chords from the outer sector. To my eye, this alteration helps indicate the direction of the flow and gives a cleaner look.
  4. I have kept the smallest flows in the plot, but plotted their chords last, so that the focus is maintained on the largest flows. Previously smaller flows were dropped according to an arbitrary cut off, which meant that the sector pieces on the outside of the circle no longer represented the total of the inflows and outflows.

Combined, these four modifications have helped me when presenting the results at recent conferences, reducing the time I need to spend explaining the plots and avoiding some of the confusion that occasionally occurred with the direction of the migration flows.

If you would like to replicate one of these plot, you can do so using estimates of the minimum migrant transition flows for the 2010-15 period and the demo R script in my migest package;

# install.packages("migest")
# install.packages("circlize")
demo(cfplot_reg2, package = "migest", ask = FALSE)

which will give the following output:

Estimated Global Migration Flows 2010-15

The code in the demo script uses the chordDiagram function, based on a recent update to the circlize package (0.3.7). Most likely you will need to either update or install the package (uncomment the install.packages lines in the code above).

If you want to view the R script in detail to see which arguments I used, then take a look at the demo file on GitHub here. I provide some comments (in the script, below the function) to explain each of the argument values.

Save and view a PDF version of the plot (which looks much better than what comes up in my non-square RStudio plot pane) using:

dev.copy2pdf(file ="cfplot_reg2.pdf", height=10, width=10)

10 thoughts on “Updated Circular Plots for Directional Bilateral Migration Data”

  1. Thanks for these remarkable visualisations.

    They make me think of a better world where news sources use imagery, like this, in their reporting.

    Example 1: An animated image of the Syrian Diaspora, with estimates at a finer time granularity than the UN gives us, would be useful. Once such a series had started, an update would explain changes in second or sub-second time to those who had made the effort to grok the previous version.

    Example 2: Speculative animated plots of flows out of the US (Canada and US separated) should the 2016 election season deliver results really objectionable to many Americans…

  2. Hi Guy,

    This is indeed a great package giving a wonderful way of visualizing data. Is it possible to plot the flows without having to plot flows that return to the sector they emanate from – that is same origin and destination? I am trying to plot hospital treatments according to regions where patients go compared to regions where they live. As the visualization is at present, it gives the false impression there are more treatments or patients in a certain region as it augments the graphed regions (sectors of the circle) with the patients who are treated in the regions they live.

    Thank you.

      1. Thanks so much Guy. Yes , exactly what I needed.

        I just need to add self.link = 1 in the chordDiagram function thus
        chordDiagram(data, self.link = 1)

        Many regards,


  3. Thanks for your great work.
    The regional system change in this estimate. Does South-eastern Asia part of Eastern Asia?

  4. Dear Guy,
    Thank you so much for your open resources provided to replicate such fantastic graphs! Im new to circlize and generally am not an informatics/statistics expert, but I am trying to visualize migration patterns of endangered marine species, particularly sea turtles using the circlize package. I have found only few examples that incorporate percentages of sectors into chordiagrams and have not been able to get the correct code. My data is composed of 10 sectors, of which 5 are migratory origins groups and 5 are analyzed foraging sites (using stable isotopes), where I differentiate between residents and recent recruits (which immigrates from the 5 origin groups). Therefore, I am interested in visualizing the percentage of recent recruits at each site and the corresponding contribution from the origin groups using chordiagrams. I would be very grateful if you could help me defining the code to insert individual recent recruit percentages into the chordiagram! greeting from Costa Rica,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s