Adaption of circlize::chordDiagramFromDataFrame()
with defaults set to allow for more effective visualisation of directional origin-destination data
mig_chord(
x,
lab = NULL,
lab_bend1 = NULL,
lab_bend2 = NULL,
label_size = 1,
label_nudge = 0,
label_squeeze = 0,
axis_size = 0.8,
axis_breaks = NULL,
...,
no_labels = FALSE,
no_axis = FALSE,
clear_circos_par = TRUE,
zero_margin = TRUE,
start.degree = 90,
gap.degree = 4,
track.margin = c(-0.1, 0.1),
points.overflow.warning = FALSE
)
Data frame with origin in first column, destination in second column and bilateral measure in third column
Named vector of labels for plot. If NULL
will use names from d
Named vector of bending labels for plot. Note line breaks do not work with facing = "bending"
in circlize.
Named vector of second row of bending labels for plot.
Font size of label text.
Numeric value to nudge labels towards (negative number) or away (positive number) the sector axis.
Numeric value to nudge lab_bend1
and lab_bend2
labels apart (negative number) or together (positive number).
Font size on axis labels.
Numeric value for how often to add axis label breaks. Default not activated, uses default from circlize::circos.axis()
Arguments for circlize::chordDiagramFromDataFrame()
.
Logical to indicate if to include plot labels. Set to FALSE
by default.
Logical to indicate if to include plot axis. Set to FALSE
by default.
Logical to run circlize::circos.clear()
. Set to TRUE
by default. Set to FALSE
if you wish to add further to the plot.
Set margins of the plotting graphics device to zero. Set to TRUE
by default.
Argument for circlize::circos.par()
.
Argument for circlize::chordDiagramFromDataFrame()
.
Argument for circlize::chordDiagramFromDataFrame()
.
Argument for circlize::chordDiagramFromDataFrame()
.
Chord diagram based on first three columns of x
. The function tweaks the defaults of circlize::chordDiagramFromDataFrame()
for easier plotting of directional origin-destination data. Users can override these defaults and pass additional tweaks using any of the circlize::chordDiagramFromDataFrame()
arguments.
The layout of the plots are designed to specifically work on plotting images into PDF devices with widths and heights of 7 inches (the default dimension when using the pdf
function). See the end of the examples for converting PDF to PNG images in R.
Fitting the sector labels on the page is usually the most time consuming task. Use the different label options, including line breaks, label_nudge
, track height in preAllocateTracks
and font sizes in label_size
and axis_size
to find the best fit. If none of the label options produce desirable results, plot your own using circlize::circos.text
having set no_labels = TRUE
and clear_circos_par = FALSE
.
# \dontrun{
library(tidyverse)
library(countrycode)
# download Abel and Cohen (2019) estimates
f <- read_csv("https://ndownloader.figshare.com/files/38016762", show_col_types = FALSE)
f
#> # A tibble: 307,833 × 9
#> year0 orig dest sd_drop_neg sd_rev_neg mig_rate da_min_open da_mi…¹ da_pb…²
#> <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1990 BDI BDI 0 0 0 0 0 0
#> 2 1990 COM BDI 0 0 0 0 0 0
#> 3 1990 DJI BDI 0 0 0 0 0 0
#> 4 1990 ERI BDI 0 0 0 0 0 38.3
#> 5 1990 ETH BDI 0 0 0 0 0 0.82
#> 6 1990 KEN BDI 30 30 75.7 51.3 207. 248.
#> 7 1990 MDG BDI 0 0 0 0.03 0 0
#> 8 1990 MWI BDI 0 0 0 0 0 98.8
#> 9 1990 MUS BDI 0 0 0 0.06 0 0
#> 10 1990 MYT BDI 0 0 0 0 0 0
#> # … with 307,823 more rows, and abbreviated variable names ¹da_min_closed,
#> # ²da_pb_closed
# use dictionary to get region to region flows
d <- f %>%
mutate(
orig = countrycode(sourcevar = orig, custom_dict = dict_ims,
origin = "iso3c", destination = "region"),
dest = countrycode(sourcevar = dest, custom_dict = dict_ims,
origin = "iso3c", destination = "region")
) %>%
group_by(year0, orig, dest) %>%
summarise_all(sum) %>%
ungroup()
d
#> # A tibble: 216 × 9
#> year0 orig dest sd_dr…¹ sd_re…² mig_r…³ da_mi…⁴ da_mi…⁵ da_pb…⁶
#> <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1990 Africa Africa 4297155 7845806 5.47e6 6.87e6 7.73e6 1.00e7
#> 2 1990 Africa Asia 240464 258816 7.24e5 2.84e5 5.54e5 8.15e5
#> 3 1990 Africa Europe 555826 664496 1.91e6 8.30e5 2.19e6 2.74e6
#> 4 1990 Africa Latin America a… 1505 2709 7.81e3 9.04e3 5.67e4 5.46e4
#> 5 1990 Africa Northern America 289058 301706 2.23e5 3.22e5 7.83e5 8.28e5
#> 6 1990 Africa Oceania 21550 23570 6.59e4 3.02e4 1.66e5 1.77e5
#> 7 1990 Asia Africa 94088 158903 2.00e5 1.02e5 9.36e4 3.53e5
#> 8 1990 Asia Asia 3616112 8617460 1.44e7 6.97e6 1.03e7 1.71e7
#> 9 1990 Asia Europe 1496141 2322839 5.48e6 2.85e6 4.21e6 6.42e6
#> 10 1990 Asia Latin America a… 14316 14343 1.07e5 2.02e4 1.36e5 1.75e5
#> # … with 206 more rows, and abbreviated variable names ¹sd_drop_neg,
#> # ²sd_rev_neg, ³mig_rate, ⁴da_min_open, ⁵da_min_closed, ⁶da_pb_closed
# 2015-2020 pseudo-Bayesian estimates for plotting
pb <- d %>%
filter(year0 == 2015) %>%
mutate(flow = da_pb_closed/1e6) %>%
select(orig, dest, flow)
pb
#> # A tibble: 36 × 3
#> orig dest flow
#> <chr> <chr> <dbl>
#> 1 Africa Africa 8.69
#> 2 Africa Asia 0.896
#> 3 Africa Europe 3.31
#> 4 Africa Latin America and the Caribbean 0.0361
#> 5 Africa Northern America 1.59
#> 6 Africa Oceania 0.264
#> 7 Asia Africa 0.907
#> 8 Asia Asia 23.8
#> 9 Asia Europe 9.14
#> 10 Asia Latin America and the Caribbean 0.233
#> # … with 26 more rows
# pdf(file = "chord.pdf")
mig_chord(x = pb)
# dev.off()
# file.show("chord.pdf")
# pass arguments to circlize::chordDiagramFromDataFrame
# pdf(file = "chord.pdf")
mig_chord(x = pb,
# order of regions
order = rev(unique(pb$orig)),
# spacing for labels
preAllocateTracks = list(track.height = 0.3),
# colours
grid.col = c("blue", "royalblue", "navyblue", "skyblue", "cadetblue", "darkblue")
)
#> Warning: Since you have set `order`, you should better set `grid.col` as a named
#> vector where sector names are the vector names, or else the color will
#> be wrongly assigned.
# dev.off()
# file.show("chord.pdf")
# multiple line labels to fit on longer labels
r <- pb %>%
sum_region() %>%
mutate(lab = str_wrap_n(string = region, n = 2)) %>%
separate(col = lab, into = c("lab1", "lab2"), sep = "\n", remove = FALSE, fill = "right")
#> Asking for more lines than words
#> Asking for more lines than words
#> Asking for more lines than words
#> Asking for more lines than words
r
#> # A tibble: 6 × 8
#> region out_mig in_mig turn net lab lab1 lab2
#> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr>
#> 1 Africa 6.10 2.52 8.62 -3.58 "Afri… Afri… NA
#> 2 Asia 18.7 6.93 25.6 -11.7 "Asia" Asia NA
#> 3 Europe 8.11 15.7 23.8 7.59 "Euro… Euro… NA
#> 4 Latin America and the Caribbean 5.90 4.39 10.3 -1.51 "Lati… Lati… and …
#> 5 Northern America 6.96 14.8 21.7 7.83 "Nort… Nort… Amer…
#> 6 Oceania 1.26 2.67 3.92 1.41 "Ocea… Ocea… NA
# pdf(file = "chord.pdf")
mig_chord(x = pb,
lab = r %>%
select(region, lab) %>%
deframe(),
preAllocateTracks = list(track.height = 0.25),
label_size = 0.8,
axis_size = 0.7
)
# dev.off()
# file.show("chord.pdf")
# bending labels
# pdf(file = "chord.pdf")
mig_chord(x = pb,
lab_bend1 = r %>%
select(region, lab1) %>%
deframe(),
lab_bend2 = r %>%
select(region, lab2) %>%
deframe()
)
# dev.off()
# file.show("chord.pdf")
# convert pdf to image file
# library(magick)
# p <- image_read_pdf("chord.pdf")
# image_write(image = p, path = "chord.png")
# file.show("chord.png")
# }